2009-03-23 9 views
3

Okay, so dass ich einen Blick auf einige Quelle zu nehmen, wenn ich auf diese kam:Python, __init__ und Selbst Verwirrung

>>> def __parse(self, filename): 
...   "parse ID3v1.0 tags from MP3 file" 
...   self.clear() 
...   try: 
...    fsock = open(filename, "rb", 0) 
...    try: 
...     fsock.seek(-128, 2) 
...     tagdata = fsock.read(128) 
...    finally: 
...     fsock.close() 
...    if tagdata[:3] == 'TAG': 
...     for tag, (start, end, parseFunc) in self.tagDataMap.items(): 
...      self[tag] = parseFunc(tagdata[start:end]) 
...   except IOError: 
...    pass 
... 

Also entschied ich mich, es zu testen.

>>> __parse("blah.mp3") 

Und erhielt ich diesen Fehler:

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: __parse() takes exactly 2 arguments (1 given) 

Dies wäre nicht das erste Mal sein, ich das erlebt habe, ich denke immer, ich bin selbst Parameterliste im Argument enthalten gemeint Aber ich weiß, dass das nicht stimmt. Könnte mir jemand erklären, warum das viel mit Code passiert, mit dem ich versuche herumzuspielen? Ich nehme an, aufgrund meines Verständnisses der Begriffe, verstehe ich kaum, was Init oder Selbst ist oder warum es relevant ist. def x (b): print b ist dasselbe wie def x (self, b): self.b = b drucke self.b, oder? Warum ist es so wichtig!

Ich möchte nur eine grundlegende Erklärung, so kann ich das aus meinem Kopf bekommen, danke.

Antwort

8

Die def __parse innerhalb einiger Klassendefinition war.

Sie können die Methode defs nicht aus den Klassendefinitionen ziehen. Die Definition der Methodenfunktion ist Teil der Klasse.

Blick auf diese beiden Beispiele:

def add(a, b): 
    return a + b 

Und

class Adder(object): 
    def __init__(self): 
     self.grand_total = 0 
    def add(self, a, b): 
     self.grand_total += a+b 
     return a+b 

Hinweise.

  1. Die Funktion verwendet self nicht.

  2. Die Klassenmethode funktioniert self verwenden. Im Allgemeinen verwenden alle Instanzmethoden self, es sei denn, sie haben spezifische Dekoratoren wie @classmethod, die etwas anderes sagen.

  3. Die Funktion hängt nicht von irgendetwas anderes sonst.

  4. Die Klassenmethode hängt davon ab, dass sie von einer Instanz der Klasse Adder aufgerufen wird; Ferner hängt es davon ab, dass die Instanz der Klasse Adder korrekt initialisiert wurde. In diesem Fall hat die Initialisierungsfunktion (__init__) gewährleistet, dass jede Instanz von Adder immer eine Instanzvariable grand_total benannt hat, und dass Instanzvariable hat einen Anfangswert von 0.

  5. Sie können die add-Methodenfunktion nicht aus der Klasse Adder ziehen und separat verwenden. Es ist keine eigenständige Funktion. Es wurde definiert innerhalb der Klasse und hat bestimmte Erwartungen wegen dieser Position innerhalb der Klasse.

+0

Ah, so init/self sollte mit Klassen verwendet werden und nicht mit defs, die nicht in Klassen sind? –

+0

Oder eher, def __init__ sollte in Klassen verwendet werden, und def was auch immer (self, ...) sollte auch in Klassen verwendet werden, Module/Methoden selbst sollten keine eigenen haben? –

+1

Technisch ist "Selbst" kein Schlüsselwort. In der Praxis sollte man so tun, als wäre es so. – Brian

0

self wird automatisch vom Wrapper der Instanzmethode für Klassen übergeben. Diese Funktion ist nicht umgebrochen. Es ist keine Methode, es ist nur eine Funktion.Es macht nicht einmal Sinn, ohne an eine Klasse gebunden zu sein, da sie den Selbstparameter benötigt.

0

Nebenbei ist es ist möglich, statische Methoden einer Klasse in Python zu erstellen. Der einfachste Weg, dies zu tun, ist über Dekoratoren (z. B. @staticmethod). Ich vermute, dass diese Art der Sache in der Regel nicht die pythonische Lösung ist.

2

Funktionen/Methoden können genannt monkeypatching in Python für eine Technik außerhalb einer Klasse und dann verwendet, geschrieben werden:

class C(object): 
    def __init__(self): 
    self.foo = 'bar' 

def __output(self): 
    print self.foo 

C.output = __output 
c = C() 
c.output() 
+0

Scheint eine Art Rundungsmethode. Hast du ein nicht-triviales Beispiel? – tgray

+0

Ich kann viele Beispiele geben, aber alle reduzieren auf das Setzen eines Attributs für eine Klasse auf eine Funktion, die außerhalb davon definiert ist. Monkeypatching ist am nützlichsten, wenn Sie die Klasse selbst nicht ändern können, entweder weil sie Teil einer anderen Bibliothek ist oder weil Sie den Quellcode nicht haben. –

+0

Ich verstehe. Danke für die Erklärung! – tgray

1

Sieht aus wie Sie ein wenig verwirrt über die Klassen und objektorientierten Programmierung sind. Das "Selbst" -Ding ist einer der Fehler in Python für Leute, die aus anderen Programmiersprachen kommen. IMO das offizielle Tutorial behandelt es nicht so gut. This tutorial scheint ziemlich gut. Wenn Sie jemals Java gelernt haben, ist self in Python this in Java sehr ähnlich. Der Unterschied besteht darin, dass Sie in Python self als erstes Argument für jede Funktion in einer Klassendefinition angeben müssen.

Wenn Python Ihre erste Programmiersprache (oder Ihre erste objektorientierte Sprache) ist, können Sie sich dies als eine einfache Faustregel merken: Wenn Sie eine Funktion definieren, die Teil einer Klasse ist, müssen Sie schließen Sie als erstes Argument self ein. Wenn Sie eine Funktion definieren, die nicht Teil einer Klasse ist, sollten Sie self nicht in die Argumente einschließen. Sie können keine Klassenfunktion nehmen und sie unabhängig machen, ohne eine (oder möglicherweise viel) zusätzliche Codierung zu machen. Schließlich, niemals self als Argument, wenn Aufruf eine Funktion.

Es gibt Ausnahmen zu diesen Regeln, aber es lohnt sich nicht, sich um sie zu kümmern.