@Atalanttore: Zuweisungen gelten grundsätzlich nur für den lokalen Namensraum. Innere Namensräume (d.h. diejenigen "unterhalb" dieses Namensraums) können entscheiden ob sie eine eigene Zuweisung machen oder ob sie eine "höher gelegene" Zuweisung verwenden. Zur Veranschaulichung hier dargestellt mit inneren Funktionen:
Code: Alles auswählen
def f():
x = 1
def g():
x = 2
print(f'Inside g(): x is {x}')
return x
print(f'Return value of g(): {g()}')
print(f'Original x inside f(): {x}')
return x
def f2():
x = 1
def g():
print(f'g() uses outer x: {x}')
return x
print(f'Return value of g(): {g()}')
print('Adding return value to x...')
x += g()
print(f'Outer x is now {x}')
print('Calling g() again...')
print(f'Return value of g(): {g()}')
return x
Bei deinem eingangs gezeigten Code-Beispiel wird ähnlich wie hier in
f2() einfach das
aa aus dem äußeren Namensraum angesprochen. Sobald man es einmal hat, unterscheiden sich die Zugriffsmöglichkeiten nicht vom "eigenen" Namensraum des Objekts. Eine Liste kann also im inneren Namensraum auf die gleiche Weise verändert werden wie in einem äußeren Namensraum. Die Regeln ob etwas lokal ist, gelten nur für den Zugriff auf den eigentlichen Bezeichner, nicht aber für das Verhalten des Objektes. Denn dieses weiß grundsätzlich nicht, in welchem Namensraum es "geholt" wurde (obskure Tricks mit dem Aufruf-Stack mal ausgenommen). Ist es so etwas klarer für dich...?