2017-01-28 1 views
3

Ich lerne Python und versuche ein Kartenspiel zu simulieren. Ich habe eine Frage zur Punktnotation. Ich habe überall im Internet nach einer bestimmten Antwort gesucht, konnte aber keine finden.Punktnotation in Python. Sollte Methode vor oder nach dem Objekt kommen?

Warum ist es, dass manchmal gelehrt werden wir so ein Verfahren in Punktnotation zu nennen:

object.methodName() 

Während andere Zeiten, die wir es so dargestellt nennen:

className.methodName(object) 

Was ist der Unterschied?

Hier ist ein spezifisches Beispiel. Dies ist eine Methode Definition aus dem Buch (Wie wie ein Informatiker denken)

class Hand(Deck): 
    def __init__ (self, name = " "): 
     self.cards = [] 
     self.name = name 

    def __str__(self): 
     s = "Hand "+ self.name 
     if self.isEmpty(): 
      return s+" is empty\n" 
     else: 
      return s+ " contains\n" + Deck.__str__(self) 

Manchmal ist das Objekt kommt, bevor das Verfahren:

self.isEmpty() 

Manchmal ist das Objekt kommt nach der Methode, in der Klammer :

Deck.__str__(self) 

Welche Methode verwenden wir? Ist es wichtig?

+2

"Deck" ist eine * Klasse *, und "Deck .__ str__" ist eine ungebundene Methode. Wenn Sie stattdessen 'self .__ str __()' ausprobiert haben, würden Sie die Methode 'Hand .__ str __()' erneut aufrufen (was zu einem unendlichen Rekursionsfehler führt), wollen Sie die Elternklasse, also wird sie explizit aufgerufen. –

+2

Das Aufrufen der Klasse wird jedoch nicht empfohlen. Verwenden Sie stattdessen 'super() .__ str __()' (und lassen Sie 'super()' herausfinden, was die Elternklasse ist und wie man 'Deck .__ str__' zu' self' richtig findet). –

+1

Sie haben die Methode '__str__' in der Unterklasse' Hand' überschrieben, so dass dies erforderlich ist, um die übergeordnete Version von '__str__' aufzurufen. Wie bereits erwähnt, sollten Sie stattdessen 'super() .__ str __()' verwenden, da es sich um kompliziertere Vererbungsstrukturen handelt. – tdelaney

Antwort

1

Sometimes the object comes after the method, in the parenthesis:

Deck.__str__(self) 

Nein, kommt das Objekt immer vor seiner eigenen Methode. In dieser Zeile befinden sich zwei Python "Objekte". Sie übergeben das Objekt self (das ist wirklich eine Klasseninstanz) als Parameter an die __str__-Methode des Objekts Deck (das ist wirklich eine Klasse).

1

If Sie verwenden:

object.methodName() 

dann Sie mit eigenen Daten die Methode einer speziellen Instanz aufrufen. Da die Methode mit der angegebenen Instanz verknüpft ist, erhalten Sie unterschiedliche Ergebnisse.

a = Hand() 
b = Hand() 

dann

a.cards 
b.cards 

können verschiedene (in den meisten Fällen) sein.

Um auf diese Daten zugreifen zu können, muss das Objekt self jede Methode verwenden. Dies geschieht durch:

def foo(self): 
    return self.cards 

Wenn Sie die Methode definieren.

Sofern Sie nicht eine spezielle Klassenmethode schreiben, als Sie immer das Selbst dort setzen müssen.

Beim Aufruf von object.methodName() erhält die Methode automatisch die Information des Objekts, zu dem sie gehört (weil Sie die Objekt-/Instanzreferenz vor dem Punkt übergeben. Diese Information wird im Parameter self gespeichert.Somit ist das Verfahren kann zum Beispiel tun: return self.cards

Aber wenn Sie es wie Deck.__str__(self) nennen, als Sie nur die Klasse haben dies bedeutet, dass es keine self ist (die die Objektreferenz ist selbst).

Die Methode weiß also nicht, zu welchen Instanzdaten sie gehört, daher müssen Sie die self übergeben.

Also summiert, wenn Sie rufen: object.__str__() die Informationen über die Instanz wird angegeben, weil Sie die Objektreferenz verwendet, um die Methode aufzurufen.

Aber wenn Sie Deck resp. die className als Sie die Informationen über die Instanz auch über className.method(self) setzen müssen, weil sonst keine Objektreferenz für eine Objektinstanz existiert.

Ich hoffe, diese Erklärung ist verständlich.

0

Im Allgemeinen kommt das Objekt zuerst.

So:

object.methodName()

Oder wie folgt aus:

self.isEmpty()

Aber ich wollte wissen, warum mein Python Buch unterrichtet mich diese eine Methode wie folgt zu nennen:

Deck.__str__(self)

Ich wollte wissen, warum "Selbst" in Klammern am Ende statt am Anfang der Methode steht. Mit anderen Worten, warum schreiben Sie es nicht so:

self.Deck._str_()

Der Grund dafür ist, dass der Code über einen Fehler werfen würde:

"Hand instance has no attribute Deck

Der obige Fehler wird verursacht, da dies geschrieben So denkt Python, dass "Deck" ein Eigenschaftsattribut ist. Aber in diesem Fall ist es nicht. Deck, ist der PARENT-Typ zum Hand-Typ, es ist kein Attribut von sich selbst.

Hier ist der Codeblock, wo Sie den fraglichen Code sehen können, sowie den Elterntyp (Deck) und den Kindtyp, mit dem ich arbeite (Hand). In diesem Code schreiben wir eine Methode zum Überschreiben der Zeichenfolgenformatierung für Hand, indem Sie auf die Zeichenfolgenformatierung in Deck zugreifen. Das Code-Snippet Deck.__str__(self) ist auf diese Weise geschrieben, weil wir eine Möglichkeit benötigen, Python mitzuteilen, von welchem ​​Typobjekt die Formatierung der Zeichenfolge kopiert werden soll. In diesem Fall wollten wir die String-Formatierung von Deck, dem übergeordneten Element.

class Hand(Deck): def __init__ (self, name = " "): self.cards = [] self.name = name

def __str__(self): 
    s = "Hand "+ self.name 
    if self.isEmpty(): 
     return s+" is empty\n" 
    else: 
     return s+ " contains\n" + Deck.__str__(self) 

auch, wie erwähnt von @ Martijn Pieters, mit SUPER: super().__str__() ist besser, als es die Art und Weise tun, ich tat: Deck.__str__(self) Wir haben noch nicht super gelernt, aber Sie können mehr darüber erfahren, es hier (https://docs.python.org/2/library/functions.html#super).Super teilt Python grundsätzlich mit, die übergeordnete Formatierung für Sie zu finden und diese zu verwenden. Viel einfacher!

Ich hoffe, dass diese Erklärung verständlich ist. Ich versuchte zu erklären, alles wieder gut zu machen, was nicht klar ist: -/

Verwandte Themen