Вызов функции класса внутри __init__

134

Я пишу код, который берет имя файла, открывает файл и анализирует некоторые данные. Я бы хотел сделать это в классе. Следующий код работает:

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__этого класса? Или я неправильно об этом думаю?

PythonJin
источник
Есть ли причина, по которой в примере кода требуется пять версий "stat"? Было бы легче читать, если бы был только один.
465b,

Ответы:

186

Вызовите функцию таким образом:

self.parse_file()

Вам также необходимо определить функцию parse_file () следующим образом:

def parse_file(self):

parse_fileМетод должен быть привязан к объекту после вызова его (потому что это не статический метод). Это делается путем вызова функции для экземпляра объекта, в вашем случае это экземпляр self.

Льюис Даймонд
источник
Да! Это было именно то, что я искал. Спасибо!
PythonJin
33

Если я не ошибаюсь, обе функции являются частью вашего класса, вы должны использовать его так:

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 08
@paritoshsingh def parse_file(self):не должен быть вложен в __init__функцию, чтобы у вас не было частично инициализированного объекта?
donrondadon
@ivanleoncz Поскольку parse_file является методом экземпляра, нам нужно использовать ссылочный объект для его вызова.
Паритош Сингх
@rong Если этот код почтенный, и вы не хотите разрешать установку файла синтаксического анализа извне, да, он должен быть вложенным.
Паритош Сингх
12

Как насчет:

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

Кстати, если у вас есть переменные с именами stat1, stat2и т.д., ситуация выпрашивая кортежа: stats = (...).

Итак, позвольте parse_fileвернуть кортеж и сохранить его в self.stats.

Затем, например, вы можете получить доступ к тому, что раньше вызывалось stat3с помощью self.stats[2].

unutbu
источник
Я согласен, я просто поместил туда self.stat1 через self.stat5, чтобы показать, что были некоторые переменные класса, которым я назначал. В реальном коде у меня есть более элегантное решение.
PythonJin
Как это следует изменить, если я хочу, чтобы parse_fileфункция была методом MyClassобъекта. Где было selfбы необходимо?
n1k31t4 01
0

В parse_file, принять selfаргумент (так же , как в __init__). Если вам нужен какой-либо другой контекст, просто передайте его в качестве дополнительных аргументов, как обычно.

Тео Клеструп Ройезон
источник
0

Вы должны объявить 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
Ионут Хулуб
источник
-13

Я думаю, что ваша проблема на самом деле связана с неправильным отступом функции инициализации. Это должно быть так

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

     def parse_file():
          pass
Zed
источник
Твой код тоже. Если вы не поставите @staticmethodдекоратор поверх parse_file
rantanplan
хотя бы добавьте недостающее selfв свой parse_fileметод.
rantanplan
К сожалению, под строкой class MyClass (): должен был быть дополнительный уровень отступов. Я исправил это выше, но вопрос остается прежним.
PythonJin