Piszę kod, który pobiera nazwę pliku, otwiera plik i analizuje niektóre dane. Chciałbym to zrobić w klasie. Poniższy kod działa:
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()
Ale wymaga to umieszczenia całej maszyny parsującej w zakresie __init__
funkcji dla mojej klasy. Teraz wygląda to dobrze w przypadku tego uproszczonego kodu, ale funkcja parse_file
ma również kilka poziomów wcięć. Wolałbym zdefiniować funkcję parse_file()
jako funkcję klasową, jak poniżej:
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
Oczywiście ten kod nie działa, ponieważ funkcja parse_file()
nie jest objęta zakresem __init__
funkcji. Czy istnieje sposób wywołania funkcji klasy z poziomu __init__
tej klasy? A może źle o tym myślę?
Odpowiedzi:
Wywołaj funkcję w ten sposób:
Musisz także zdefiniować swoją funkcję parse_file () w następujący sposób:
def parse_file(self):
parse_file
Metoda musi być związany z obiektem na nazywając ją (bo to nie jest metoda statyczna). Odbywa się to poprzez wywołanie funkcji na instancji obiektu, w twoim przypadku jest to instancjaself
.źródło
Jeśli się nie mylę, obie funkcje są częścią twojej klasy, powinieneś używać ich w następujący sposób:
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
zastąp linię:
z:
źródło
self.parse_file()
a nieparse_file()
?def parse_file(self):
nie powinno być zagnieżdżone w__init__
funkcji, aby nie mieć częściowo zainicjowanego obiektu?Co powiesz na:
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
Nawiasem mówiąc, jeśli masz zmienne o nazwach
stat1
,stat2
itp, sytuacja jest żebranie na krotki:stats = (...)
.Zwróćmy więc
parse_file
krotkę i zapiszmy ją wself.stats
.Następnie, na przykład, możesz uzyskać dostęp do tego, co było wywoływane za
stat3
pomocąself.stats[2]
.źródło
parse_file
funkcja była metodąMyClass
obiektu. Gdzie byłobyself
to konieczne?W
parse_file
, weźself
argument (tak jak w__init__
). Jeśli potrzebujesz innego kontekstu, po prostu przekaż go jako dodatkowe argumenty, jak zwykle.źródło
Musisz zadeklarować parse_file w ten sposób;
def parse_file(self)
. Parametr „self” jest ukrytym parametrem w większości języków, ale nie w Pythonie. Musisz dodać go do definicji wszystkich metod należących do klasy. Następnie możesz wywołać funkcję z dowolnej metody wewnątrz klasy za pomocąself.parse_file
Twój ostateczny program będzie wyglądał następująco:
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
źródło
Myślę, że twój problem w rzeczywistości polega na nieprawidłowym wcięciu funkcji init. Powinno być tak
class MyClass(): def __init__(self, filename): pass def parse_file(): pass
źródło
@staticmethod
dekoratora na wierzchuparse_file
self
w swojejparse_file
metodzie.