【问题标题】:Can I add methods into def __init__?我可以在 def __init__ 中添加方法吗?
【发布时间】:2016-01-22 18:23:04
【问题描述】:

使用 python 2.7.6,我一直在尝试编写一个类,该类可以从给定 zip 文件中的几个 xml 文件中提取 xml 数据片段。一旦我使用班级,我希望能够以任何顺序使用任何方法,因此希望解压缩阶段在班级的幕后进行。

这是我第一次真正尝试真正使用一个类,因为我对 python 还很陌生,所以我边走边学。

我定义了将数据解压缩到内存的方法,并在其他方法中使用了这些方法 - 然后意识到使用多种方法时效率会非常低。由于解压步骤对于类中的任何方法都是必需的,有没有办法将其构建到 init 定义中,以便仅在首次创建类时执行一次?

我目前拥有的示例:

class XMLzip(object):
    def __init__(self, xzipfile):
        self.xzipfile = xzipfile

    def extract_xml1(self):
        #extract the xmlfile to a variable

    def extract_xml2(self):
        #extract xmlfile2 to a variable

    def do_stuff(self):
        self.extract_xml1()
        ....

    def do_domethingelse(self):
        self.extract_xml1()

有没有办法像我在下面显示的那样做?如果是这样,它叫什么 - 我的搜索效果不是很好。

class XMLzip(object):
    def __init__(self, xzipfile):
        self.xzipfile = xzipfile

        def extract_xml1()
            # extract it here

        def extract_xml2()
            # extract it here

    # Now carry on with normal methods
    def do_stuff(self):
        ...

【问题讨论】:

  • 是的,有可能吗?问题是什么?为什么不直接使用__init__ 中的提取方法而不是在那里定义它们?
  • 这是怎么做的?我从未在示例中见过它。它有名字吗?它可能会帮助我搜索一个。
  • 你的意思是像我现在一样定义提取方法,但在初始化部分调用它们?这怎么能行?
  • 为什么不呢?我会发布一个答案。
  • 要接受 Python 的 __init__() 的性质,请查看它的名称。它不是构造函数,而是 initializer!当您调用您的类时(xml_zip = XMLzip(my_xzip_file),该类的实例将分两步进行实例化:构造一个对象(Python 运行时的工作,而不是您的类的),然后然后 该对象和任何类调用参数被传递给__init__() 用于初始化对象。因为已经创建了对象,所以可以像在任何其他方法中一样调用方法。显然,运行__init__() 本身的效果不存在。

标签: python python-2.7 class


【解决方案1】:

__init__ 中,你可以做任何你想做的事情来初始化你的类,在这种情况下,看起来你需要的是这样的

class XMLzip(object):
    def __init__(self, xzipfile):
        self.xzipfile = xzipfile
        self.xml1 = #extract xml1 here
        self.xml2 = #extract xml2 here

    def do_stuff(self):
        ...

如果您只想执行一次提取部分,请执行此操作并将结果保存在您的类实例中的附加属性中。

我怀疑提取过程非常相似,因此您可以根据自己的喜好将其设为类内或类外的函数,并提供额外的参数来处理特殊性,例如像这样

外部版本

def extract_xml_from_zip(zip_file,this_xml):
    # extract the request xml file from the given zip_file
    return result

class XMLzip(object):
    def __init__(self, xzipfile):
        self.xzipfile = xzipfile
        self.xml1 = extract_xml_from_zip(xzipfile,"xml1")
        self.xml2 = extract_xml_from_zip(xzipfile,"xml2")

    def do_stuff(self):
        ...

内部版本

class XMLzip(object):
    def __init__(self, xzipfile):
        self.xzipfile = xzipfile
        self.xml1 = self.extract_xml_from_zip("xml1")
        self.xml2 = self.extract_xml_from_zip("xml2")

    def extract_xml_from_zip(self,this_xml):
        # extract the request xml file from the zip_file in self.xzipfile
        return result

    def do_stuff(self):
        ...

【讨论】:

  • 你的内部版本不会在定义之前调用函数extract_xml_from_zip吗?我认为 Python 不允许这样做。您可以在类之外编写函数(如科波菲尔的第一个示例),或者在定义 __init__ 之前定义 extract_xml_from_zip
  • @yeshua 执行顺序和定义顺序不一样,所有的东西都是先定义编译但不执行,运行代码就执行了。。。自己试试举个小例子
【解决方案2】:

您可以在初始化程序中调用您在类中定义的任何方法。

演示:

>>> class Foo(object):
...    def __init__(self):
...        self.some_method()
...    def some_method(self):
...        print('hi')
... 
>>> f = Foo()
hi

我从您的问题中得知您只需要提取一次文件。保留您的课程并使用__init__ 中的提取方法并为提取的内容设置所需的属性/变量。

例如

def __init__(self, xzipfile):
    self.xzipfile = xzipfile
    self.extract1 = self.extract_xml1()
    self.extract2 = self.extract_xml2()

这当然要求你的提取方法有一个返回值,别忘了。

【讨论】:

  • 很好的答案谢谢@timgeb,如果其他人看到这个问题,我只是根据给出的选项接受了另一个。不过还是谢谢。
猜你喜欢
  • 1970-01-01
  • 2017-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-23
  • 1970-01-01
  • 1970-01-01
  • 2019-07-17
相关资源
最近更新 更多