Ich denke, die tutorial Leider ist (weil mehrdeutig) formuliert und durch
[d] ata Attribute überschreiben Methode mit dem gleichen Namen Attribute
bedeutet tatsächlich „Datenüberschreibung Attribute vorher zugeordnet/definierte Methodenattribute gleichen Namens und umgekehrt: Methodenattribute überschreiben zuvor zugeordnete/definierte Datenattribute gleichen Namens. "
„Duh“, Sie vielleicht denken, „Daten-Attribute auch vorher Daten Attribute mit dem gleichen Namen zugewiesen außer Kraft setzen, so was ist das Problem? Warum ist das einmal erwähnt?“ Das Zuweisen und Neuzuweisen (in dem zitierten Lernprogramm als "Überschreiben" bezeichnet) zu Variablen (ob sie "Attribute" von etwas oder nicht heißen) ist schließlich eines der prototypischen Merkmale einer imperativen Programmiersprache.
Nun, lassen Sie mich Ihnen vorstellen zu
Namespaces
Python Klassen Namespaces sind. Das Lernprogramm könnte also versuchen, hier zu sagen, dass die Datenattribute und Methodenattribute innerhalb einer Klasse einen Namespace teilen.
Dies gilt jedoch nicht für Attribute verschiedener Klassen. Wenn eine Klasse von einer anderen Klasse erbt, hat sie Zugriff auf die Namen ihrer Eltern. Wenn ein Name für die Methodendefinition oder die Datenzuweisung innerhalb der erbenden Klasse wiederverwendet wird, behält die übergeordnete Klasse die ursprünglichen Werte bei. In der Kinderklasse sind sie nur vorübergehend beschattet. Wenn Sie den Namen aus der untergeordneten Klasse entfernen, es auch wieder Zugriff auf das Attribut des gleichen Namen der Eltern bieten:
class A:
x = 111
class B1(A):
x = 123 # Shadows A.x
assert B1.x == 123
del B1.x # But after removing B1's own x attribute ...
assert B1.x == 111 # ... B1.x is just an alias to A.x !
# Shadowing can happen at any time:
class B2(A):
pass
assert B2.x == A.x == 111
B2.x = 5 # shadowing attributes can also be added after the class definition
assert B2.x == 5
assert A.x == 111
del B2.x
assert B2.x == A.x == 111
Kontrast dies mit Neudefinition auch bekannt alsZu (oder „Überschreiben“, wie das Tutorial es nennt):
class C:
x = 555
def x(self):
print('I am x')
C().x() # outputs "I am x"
del C.x
print(C.x) # AttributeError: 'C' object has no attribute 'x'
Methode C.x()
nicht vorübergehend Daten Schatten hat Attribut C.x
. Er hat es ersetzt. Wenn wir also die Methode löschen, fehlt x
vollständig innerhalb von C
, anstatt dass das Datenattribut unter diesem Namen wieder erscheint.
Mehr Namespaces
Instanziierung fügt einen weiteren Namensraum und somit eine weitere Chance für Shadowing:
a = A()
assert a.x == 111 # instance namespace includes class namespace
a.x = 1000
assert a.x == 1000
assert A.x == 111 # class attribute unchanged
del a.x
assert a.x == 111 # sees A.x again
In der Tat, alle (verschachtelte) Namensräume in Python arbeiten auf diese Weise: Pakete, Module, Klassen, Funktionen und Methoden, Instanzobjekte, innere Klassen, verschachtelte Funktionen ...
Beim Lesen einer Variablen wird die Namensraumhierarchie von unten nach oben durchlaufen, bis der Name gefunden wurde. (Hier lesen bedeutet bedeutet, den Wert (Objekt, Funktion/Methode oder Built-In) zu finden, an den der Name der Variablen gebunden ist. Wenn der Wert veränderbar ist, kann dieser auch zum Ändern des Werts verwendet werden.)
Ein Andererseits wird beim Setzen (Definieren oder Neudefinieren) einer Variablen ein Name des aktuellen Namensraums verwendet: Rebound auf den neuen Wert, wenn der Name bereits in diesem Namespace existiert (und nicht nur dort von einem anderen Namespace enthalten ist) oder a neu erstellter Name, falls dieser noch nicht existiert
Variablen können Schatten auf andere Variablen ... Methoden und Attribute und Klassen und Funktionen sind alle nur Variablen –