在__init__中调用类函数

223

我正在编写一个程序,它需要读取一个文件名,打开该文件,并解析一些数据。我想用类的形式来实现。以下代码可以实现这个功能:

class MyClass():
    def __init__(self, filename):
        self.filename = filename 

        self.stat1 = None
        self.stat2 = None
        self.stat3 = None
        self.stat4 = None
        self.stat5 = None

        def parse_file():
            #do some parsing
            self.stat1 = result_from_parse1
            self.stat2 = result_from_parse2
            self.stat3 = result_from_parse3
            self.stat4 = result_from_parse4
            self.stat5 = result_from_parse5

        parse_file()

但是这需要将所有解析机制放在我的类的__init__函数的范围内。虽然对于这个简化的代码看起来很好,但是parse_file函数也有相当多的缩进级别。我更希望像下面这样将函数parse_file()定义为一个类函数:

class MyClass():
    def __init__(self, filename):
        self.filename = filename 

        self.stat1 = None
        self.stat2 = None
        self.stat3 = None
        self.stat4 = None
        self.stat5 = None
        parse_file()

    def parse_file():
        #do some parsing
        self.stat1 = result_from_parse1
        self.stat2 = result_from_parse2
        self.stat3 = result_from_parse3
        self.stat4 = result_from_parse4
        self.stat5 = result_from_parse5

当然这段代码不能运行,因为函数parse_file()不在__init__函数的范围内。有没有一种方法可以从该类的__init__中调用一个类函数?或者我想错了吗?


3
为什么代码示例需要五个“stat”版本?如果只有一个版本,阅读起来会更容易。 - 465b
6个回答

303

以这种方式调用函数:

self.parse_file()

你还需要像这样定义你的parse_file()函数:

def parse_file(self):

parse_file方法在调用时必须绑定到一个对象上(因为它不是静态方法)。这可以通过在对象实例上调用函数来完成,你的情况下实例是self


60

如果我没错的话,这两个函数都是你的类的一部分,你应该像这样使用它:

class MyClass():
    def __init__(self, filename):
        self.filename = filename 

        self.stat1 = None
        self.stat2 = None
        self.stat3 = None
        self.stat4 = None
        self.stat5 = None
        self.parse_file()

    def parse_file(self):
        #do some parsing
        self.stat1 = result_from_parse1
        self.stat2 = result_from_parse2
        self.stat3 = result_from_parse3
        self.stat4 = result_from_parse4
        self.stat5 = result_from_parse5

替换您的行:

parse_file() 

使用:

self.parse_file()

你能解释一下为什么必须使用 self.parse_file() 而不是 parse_file() 吗? - ivanleoncz
@paritoshsingh 应该将 def parse_file(self): 放在 __init__ 函数之外,这样您就不会有一个部分初始化的对象了。 - ron_g
@ivanleoncz由于parse_file是实例方法,我们需要使用引用对象来调用它。 - Paritosh Singh
如果这段代码容易受到攻击,而且你不想允许从外部设置解析文件,那么它应该被嵌套。 - Paritosh Singh
考虑使用静态方法 https://www.programiz.com/python-programming/methods/built-in/staticmethod - Sandesh Ghanta

18

怎么样:

class MyClass(object):
    def __init__(self, filename):
        self.filename = filename 
        self.stats = parse_file(filename)

def parse_file(filename):
    #do some parsing
    return results_from_parse
顺便提一下,如果你有名为stat1stat2等的变量,情况就需要使用元组了:stats = (...)
因此让parse_file返回一个元组,并将该元组存储在self.stats中。
然后,例如,你可以使用self.stats[2]来访问以前称为stat3的内容。

我同意,我只是把self.stat1到self.stat5放在那里,以显示我正在分配一些类变量。在实际代码中,我有一个更优雅的解决方案。 - PythonJin
如果我想让parse_file函数成为MyClass对象的一个方法,应该如何修改?在哪里需要使用self - n1k31t4

1

您必须像这样声明parse_file; def parse_file(self)。在大多数语言中,“self”参数是一个隐藏的参数,但在Python中不是。您必须将其添加到属于类的所有方法的定义中。 然后,您可以使用self.parse_file从类内任何方法调用该函数。

您的最终程序将如下所示:

class MyClass():
  def __init__(self, filename):
      self.filename = filename 

      self.stat1 = None
      self.stat2 = None
      self.stat3 = None
      self.stat4 = None
      self.stat5 = None
      self.parse_file()

  def parse_file(self):
      #do some parsing
      self.stat1 = result_from_parse1
      self.stat2 = result_from_parse2
      self.stat3 = result_from_parse3
      self.stat4 = result_from_parse4
      self.stat5 = result_from_parse5

0
在`parse_file`函数中,像`__init__`一样使用`self`参数。如果需要其他上下文,则按照通常的方式将其作为附加参数传递。

-15

我认为您的问题实际上是因为未正确缩进init函数所导致的。应该像这样:

class MyClass():
     def __init__(self, filename):
          pass

     def parse_file():
          pass

1
除非您在 parse_file 顶部放置 @staticmethod 装饰器,否则您的代码也不是静态方法。 - rantanplan
在你的parse_file方法中至少添加缺失的self - rantanplan
抱歉,在“class MyClass():”行下应该有一个额外的缩进层级。我已经在上面修复了它,但问题仍然存在。 - PythonJin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接