Aufrufen einer Klassenfunktion innerhalb von __init__

132

Ich schreibe einen Code, der einen Dateinamen annimmt, die Datei öffnet und einige Daten analysiert. Ich würde das gerne in einer Klasse machen. Der folgende Code funktioniert:

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()

Aber ich muss die gesamte Parsing-Maschinerie in den __init__Funktionsumfang meiner Klasse aufnehmen. Für diesen vereinfachten Code sieht das jetzt gut aus, aber die Funktion parse_fileweist auch einige Einrückungsstufen auf. Ich würde es vorziehen, die Funktion parse_file()wie folgt als Klassenfunktion zu definieren :

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

Natürlich funktioniert dieser Code nicht, da die Funktion parse_file()nicht im __init__Funktionsumfang liegt. Gibt es eine Möglichkeit, eine Klassenfunktion innerhalb __init__dieser Klasse aufzurufen ? Oder denke ich falsch darüber nach?

PythonJin
quelle
Gibt es einen Grund, warum das Codebeispiel fünf Versionen von "stat" benötigt? Es würde das Lesen erleichtern, wenn es nur einen geben würde.
465b

Antworten:

183

Rufen Sie die Funktion folgendermaßen auf:

self.parse_file()

Sie müssen Ihre parse_file () -Funktion auch folgendermaßen definieren:

def parse_file(self):

Die parse_fileMethode muss beim Aufruf an ein Objekt gebunden werden (da es sich nicht um eine statische Methode handelt). Dies erfolgt durch Aufrufen der Funktion für eine Instanz des Objekts, in Ihrem Fall für die Instanz self.

Lewis Diamond
quelle
Ja! Genau das habe ich gesucht. Danke dir!
PythonJin
33

Wenn ich mich nicht irre, sind beide Funktionen Teil Ihrer Klasse. Sie sollten sie folgendermaßen verwenden:

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

Ersetzen Sie Ihre Leitung:

parse_file() 

mit:

self.parse_file()
Paritosh Singh
quelle
Können Sie erklären, warum es verwendet werden muss self.parse_file()und nicht parse_file()?
ivanleoncz
@paritoshsingh sollte def parse_file(self):nicht unter der __init__Funktion verschachtelt sein, damit Sie kein teilweise initialisiertes Objekt haben?
Donrondadon
@ivanleoncz Da parse_file eine Instanzmethode ist, müssen wir ein Referenzobjekt verwenden, um dasselbe aufzurufen.
Paritosh Singh
@rong Wenn dieser Code ehrwürdig ist und Sie nicht zulassen möchten, dass die Analysedatei von außen festgelegt wird, sollte er verschachtelt sein.
Paritosh Singh
12

Wie wäre es mit:

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

Übrigens, wenn Sie Variablen usw. benannt stat1haben stat2, bittet die Situation um ein Tupel : stats = (...).

Lassen Sie also parse_fileein Tupel zurückgeben und das Tupel darin aufbewahren self.stats.

Dann wird zum Beispiel, können Sie was Zugriff verwendet aufgerufen werden , stat3mit self.stats[2].

unutbu
quelle
Ich stimme zu, ich habe nur self.stat1 bis self.stat5 eingefügt, um zu zeigen, dass es einige Klassenvariablen gab, denen ich zugewiesen habe. Im eigentlichen Code habe ich eine elegantere Lösung.
PythonJin
Wie soll dies geändert werden, wenn die parse_fileFunktion eine Methode des MyClassObjekts sein soll? Wo wäre selfdas nötig?
n1k31t4
0

In parse_filenehmen Sie das selfArgument (wie in __init__). Wenn Sie einen anderen Kontext benötigen, übergeben Sie ihn wie gewohnt als zusätzliche Argumente.

Teo Klestrup Röijezon
quelle
0

Sie müssen parse_file wie folgt deklarieren. def parse_file(self). Der Parameter "self" ist in den meisten Sprachen ein versteckter Parameter, in Python jedoch nicht. Sie müssen es der Definition aller Methoden hinzufügen, die zu einer Klasse gehören. Dann können Sie die Funktion von jeder Methode innerhalb der Klasse mit aufrufenself.parse_file

Ihr endgültiges Programm wird folgendermaßen aussehen:

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
Ionut Hulub
quelle
-13

Ich denke, dass Ihr Problem tatsächlich darin besteht, die Init- Funktion nicht richtig einzurücken. Es sollte so sein

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

     def parse_file():
          pass
Zed
quelle
Weder ist dein Code. Es sei denn, Sie legen den @staticmethodDekorateur darauf parse_file
Rantanplan
füge zumindest die fehlenden hinzu self in Ihrer parse_fileMethode hinzu.
Rantanplan
Hoppla, es tut mir leid, dass unter der Zeile "class MyClass ():" eine zusätzliche Einrückungsebene vorhanden sein sollte. Ich habe es oben behoben, aber die Frage bleibt dieselbe.
PythonJin