Виклик функції класу всередині __init__


132

Я пишу якийсь код, який приймає ім'я файлу, відкриває файл та аналізує деякі дані. Я хотів би це зробити на уроці. Наступний код працює:

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


Чи є причина, що для прикладу коду потрібно п'ять версій "stat"? Це було б легше читати, якби був лише один.
465б

Відповіді:


183

Викличте функцію таким чином:

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

@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].


Я згоден, я просто поклав туди self.stat1 через self.stat5, щоб показати, що існували деякі змінні класу, до яких я призначав. У фактичному коді у мене є більш елегантне рішення.
PythonJin

Як це слід змінити, якщо я хочу, щоб parse_fileфункція була методом MyClassоб'єкта. Де було selfб потрібно?
n1k31t4

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

Я думаю, що ваша проблема насправді з неправильним відступом функції init. Це повинно бути таким

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

     def parse_file():
          pass

Ні ваш код. Якщо ви не поставите @staticmethodдекоратор поверх parse_file
рантанплан

принаймні додайте відсутні selfу своєму parse_fileметоді.
рантанплан

На жаль, у рядку "class MyClass ():" повинен бути додатковий шар відступу. Я виправив це вище, але питання залишається тим самим.
PythonJin
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.