2017-05-10 3 views
1

Bei dem Versuch, mit einer Hand-Klasse für ein Kartenspiel zu kommen ich ein seltsames Verhalten von einem Attribute angetroffenKlasse Attribut funktioniert nicht richtig (Python)

wenn ich versuche self.number gesehen einstellen darunter die gewohnt zeigen korrekte Ausgabe aber wenn ich das gleiche Argument durch eine Funktion machen total() es funktioniert

meine Frage ist: warum ist das Attribut self.number nicht den Wert von len(self.cards) bekommen?

class Hand (object): 

def __init__(self,number=0,cards=[]): 

    self.cards=cards 

    self.number=len(self.cards) 

def total(self): 
    return len(self.cards) 

hand=Hand() 
hand.cards.append(9) 

print hand.cards 
print len(hand.cards) 
print hand.number 
print hand.total() 

output: 
[9] 
1 
0 #I want this to be equal to 1 
1 

Antwort

4

Das Attribut self.number wird bei Instanziierung festgelegt, verwenden Sie stattdessen eine Eigenschaft.

+0

also für alle a: __init __ (a): self.a = a werden nur geprüft und während der Initiierung verwendet danke für die Hilfe :) –

+0

@Jared der '@ property' Dekorateur spart nur Zeit und Mühe durch, unter anderem Dinge, die mir automatisch 'set' und' get' Befehle geben, ist das richtig? Man könnte dasselbe erreichen, indem man Aspekte der "Eigenschaft" von Hand definiert. Vielen Dank! – patrick

+1

@patrick: Der @property-Dekorator macht die von ihm erstellte Methode zu einem Getter. Benutzer der Klasse können auf "Nummer" zugreifen, als wäre es ein Attribut. Um einen Setter zu erstellen, dekorieren Sie die Setter-Methode mit '@ attribute_name.setter' (in diesem Fall wäre es' @ number.setter'). –

2

Wenn Sie eine Instanzvariable auf einen Ausdruck setzen, wird keine Bindung zwischen den Eingaben dieses Ausdrucks und dem Wert der Instanzvariablen erstellt. Mit anderen Worten bedeutet die Einstellung self.number auf len(self.cards) nicht, dass self.number aktualisiert wird, wenn Sie self.cards aktualisieren.

Ihr Programm ordnungsgemäß funktioniert: Wenn Sie Ihr Objekt erstellen, ist len(self.cards) 0, so self.number auf 0 gesetzt wird, wenn Sie hand.cards ändern, gibt es keine Aussagen zu ändern self.number, so bleibt es 0.

die ordnungsgemäße Möglichkeit, Ihr self.number Attribut-Update ist eine getter-setter pair zu verwenden, um sicherzustellen, dass self.number ändert sich immer wenn self.cards ändert.

Die pythonische Art, ein Getter-Setter-Paar zu erstellen, ist die Verwendung des @property decorator.

In Ihrem Fall könnte man es so machen:

class Hand(object): 
    def __init__(self, number = 0, cards = None): 
     self.cards = cards or [] 

    @property 
    def number(self): 
     return len(self.cards) 

Auf diese Weise, obwohl es jedem verwendet Ihre Klasse sieht, dass sie ein Attribut lesen, was eigentlich unter der Haube passiert ist, dass die number() Methode wird aufgerufen und berechnet korrekt die aktuelle Länge von self.cards.

+0

Ich verstehe jetzt - danke für die Hilfe :) –

Verwandte Themen