Eine kurze Notiz aus der Serie "Sie wurden gewarnt."
Der Wechsel von klassischen Programmiersprachen zu Python bringt viele Überraschungen.
Lesen Sie die Dokumentation:
Im Allgemeinen beziehen sich Instanzvariablen auf Daten, die für jede Instanz eindeutig sind, und Klassenvariablen auf Attribute und Methoden, die von allen Instanzen der Klasse gemeinsam genutzt werden
Versuchen wir mal herumzuspielen
class Vessel:
Erstellen Sie zwei Objekte und überprüfen Sie die Werte
aller Attribute:
Iowa = Vessel("Iowa") Drum=Vessel("Drum") printAttr(Iowa, Drum) >>name=Iowa vtype=boat __class__.vtype=boat >>name=Drum vtype=boat __class__.vtype=boat
Soweit wie erwartet.
Lassen Sie uns versuchen, vtype zu ändern: Dies kann auf zwei Arten erfolgen, die im Wesentlichen nur unterschiedliche Syntax derselben sind
Vessel.vtype = "USS boat" printAttr(Iowa, Drum) >>name=Iowa vtype=USS boat __class__.vtype=USS boat >>name=Drum vtype=USS boat __class__.vtype=USS boat Iowa.__class__.vtype = 'USS WW2 Boat' printAttr(Iowa, Drum) >>name=Iowa vtype=USS WW2 Boat __class__.vtype=USS WW2 Boat >>name=Drum vtype=USS WW2 Boat __class__.vtype=USS WW2 Boat
Und wieder ist alles in Ordnung.
Versuchen wir nun, dasselbe über das Attribut des Objekts zu tun.
Drum.vtype = 'submarine' printAttr(Iowa, Drum) >>name=Iowa vtype=USS WW2 Boat __class__.vtype=USS WW2 Boat >>name=Drum vtype=submarine __class__.vtype=USS WW2 Boat
Und hier ist die erste Überraschung: Trotz der Tatsache, dass vtype ein Attribut einer Klasse ist, wird es plötzlich ein Attribut eines Objekts.
Überprüfen Sie:
Vessel.vtype = "NAVY Museum" >>name=Iowa vtype=NAVY Museum __class__.vtype=NAVY Museum >>name=Drum vtype=submarine __class__.vtype=NAVY Museum
Was ist, wenn ...
del Drum.vtype >>name=Iowa vtype=NAVY Museum __class__.vtype=NAVY Museum >>name=Drum vtype=NAVY Museum __class__.vtype=NAVY Museum
Und wieder ein Klassenattribut.
Der folgende Ausdruck wird nicht mehr übergeben
del Drum.vtype printAttr(Iowa, Drum) del Drum.vtype AttributeError: vtype
Im letzten Beispiel werden Klassenüberschreibungen emuliert und das Attribut vtype entfernt.
Drum.vtype = 'submarine' del Vessel.vtype printAttr(Iowa, Drum) >>name=Iowa >>name=Drum vtype=submarine
Wenn Sie anfangen, sich mit Namespace zu befassen, wird dieses Verhalten verständlich.
Für Programmierer, die zuvor mit normalen Sprachen gearbeitet haben, scheint dies jedoch zumindest seltsam. Und wenn wir über große Projekte sprechen, die von mehreren Generationen von Entwicklern unterstützt werden, kann sich herausstellen, dass Fristen usw. nicht eingehalten wurden.
Unter Berücksichtigung des Konzepts von Python, dass alles für alle offen ist, können Sie auf die "coolen" Attribute nur über __class__ oder dessen Analog zugreifen. Meiner Meinung nach würde dies zumindest irgendwie vor Überraschungen schützen und mich zehnmal zum Nachdenken bringen, bevor ich Klassenattributen auf Objektebene etwas zuweise.
Update: Text PrintAttr
def printAttr(*o): for a in o: print(a)