Code: Alles auswählen
>>> def foo(): a=2
...
>>> foo.__dict__
{}
Code: Alles auswählen
>>> def foo(): pass
...
>>> foo.a=2
>>> foo.__dict__
{'a': 2}
Code: Alles auswählen
>>> def foo(): a=2
...
>>> foo.__dict__
{}
Code: Alles auswählen
>>> def foo(): pass
...
>>> foo.a=2
>>> foo.__dict__
{'a': 2}
Code: Alles auswählen
>>> def foo():
... a = 42
... return a
...
>>> foo.__dict__
{}
>>> foo.bar = 'Hello World'
>>> foo.__dict__
{'bar': 'Hello World'}
>>> foo.bar
'Hello World'
Code: Alles auswählen
def foo():
a=2
print(foo.__dict__)
foo()
Code: Alles auswählen
>>> def foo():
... a=2
... fuu()
...
>>> def fuu():
... print(foo.a)
...
>>> foo()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in foo
File "<stdin>", line 2, in fuu
AttributeError: 'function' object has no attribute 'a'
Diese Art von Missverständnissen möchte ich gerne beseitigen.Erwartung offenbart ein größeres Missverständnis der Semantik von Python, insbesondere derjenigen der Bindungen und Namensräume
Inwiefern widerspricht das meiner Aussage? Lokale und globale Variablen innerhalb einer Funktion werden nie im __dict__ des Funktionsobjektes landen. a gibt es nur solange die Funktion ausgeführt wird. Wenn die Funktion zurückkehrt, ist a futsch.Goswin hat geschrieben:@Heiduel:
Was ich erreichen möchte, ist die Feinheiten der Funktionsweise von Python zu verstehen.
Deine Aussage "Wenn die Funktion zurückkehrt, ist das ganze WIEDER weg" [meine Hervorhebung] stimmt wohl nicht ganz. Wenn ich nämlich vorgehe wie inalso auf foo.__dict__ zugreife BEVOR ich die Funktion verlasse, dann erhalte ich ebenfalls "{}". Sollte foo.__dict__ vielleicht nur die globals enthalten?Code: Alles auswählen
def foo(): a=2 print(foo.__dict__) foo()
a ist eine lokale Variable, die nur innerhalt der Funktion gültig ist. Sie ist nicht an das Funktionsobject gebunden. Wenn du Zugriff auf die lokalen Variablen willst, dann könntest du mittels locals() die Variablen explizit übergeben:Mir schwebte etwas wie folgt vor:da geschieht der Zugriff WÄHREND die Funktion foo noch läuft.Code: Alles auswählen
>>> def foo(): ... a=2 ... fuu() ... >>> def fuu(): ... print(foo.a) ... >>> foo() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 3, in foo File "<stdin>", line 2, in fuu AttributeError: 'function' object has no attribute 'a'
Code: Alles auswählen
>>> def foo():
... a=2
... fuu(locals())
...
>>> def fuu(foo_locals):
... print(foo_locals['a'])
Code: Alles auswählen
>>> def func(): pass
...
>>> func.a = 5
>>> func.__dict__
{'a': 5}
Code: Alles auswählen
>>> def func():
... func.a += 1
...
>>> func.a = 1
>>> func.a
1
>>> func()
>>> func.a
2
Das ist für mich in Ordnung, ich will ja gar nichts ändern, sondern nur lesen.lunar hat geschrieben: Immerhin bedeutet es, dass man den lokalen Namensraum über "locals()" nicht ändern kann.
Code: Alles auswählen
def zeige(locs,expr):
print( "{} = {}".format(expr.strip(),eval(expr,locs)) )
def foo():
a=2
zeige(locals(),'a+1')
foo() #druckt "a+1 = 3"
Wie ist folgende Empfehlung aus PEP_8 zu verstehen:BlackJack hat geschrieben:[Namen die mit mit Unterstrich beginnen] macht dann eigentlich nur Sinn bei Namen auf Modulebene, Methodennamen, und Attributnamen, die nicht zur öffentlichen Schnittstelle Deiner Objekte gehören.
Sind hier statt "Instanzvariablen" vielleicht "Klassennamen" gemeint?Benutze einen führenden Unterstrich nur für nicht-öffentliche Methoden und Instanzvariablen.