__init__ und keyword arguments

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
tommot
User
Beiträge: 2
Registriert: Freitag 11. Oktober 2019, 12:37

Hallo Python Forum,

kann mir bitte jemand das Folgende Verhalten erklären:
Angenommen ich habe die Klasse

Code: Alles auswählen

class Test:
	def __init__(self, foo={}):
		print(foo)
		self.foo = foo
wenn ich diese Mehrmals ohne Argumente instanziere und den Inhalt verändere, verhält sich foo wie eine Klassenvariable, nicht wie eine Instanzvariable
also:

Code: Alles auswählen

# Ausgabe {}
f1 = Test()
f1.foo["a"] = 1

# Ausgabe  {"a": 1}
f2 = Test()
Ich benutze jetzt **kw_args um das Problem zu umgehen

Also so:

Code: Alles auswählen

class Test():
	def __init__(self, *args, **kw_args):
		self.foo = kw_args.get("foo", {})
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Der grosse Klassiker. Das hat nix mit __init__ zu tun, sondern ist das Standardverhalten in allen Methoden oder Funktionen: veraenderliche Default-Argumente werden nur EINMAL angelegt, naemlich wenn die Definition "def irgendwas(...)" ausgewertet wird. NICHT beim Aufruf.

So kannst du also nicht vorgehen. Das Standardvorgehen besteht darin, None zu verwenden, und darauf zu pruefen.

Code: Alles auswählen

def foo(args=None):
    if args is None:
        args = {}
    ... 
Sirius3
User
Beiträge: 18270
Registriert: Sonntag 21. Oktober 2012, 17:20

Defaultargumente werden erzeugt, wenn die Funktion definiert wird, damit haben alle Test-Instanzen, die dieses Default-Argument benutzen auch das selbe Objekt, das selbe Wörterbuch. Das hat nichts damit zu tun, ob die Funktion Methode einer Klasse ist, das ist auch bei ganz normalen Funktionen so. Üblicherweise nimmt man als Defaultargument None, und erzeugt in diesem Fall ein neues Wörterbuch:

Code: Alles auswählen

class Test:
    def __init__(self, foo=None):
        print(foo)
        self.foo = {} if foo is None else foo
Übrigens, eingerückt wird immer mit 4 Leerzeichen pro Ebene, keine Tabs.
tommot
User
Beiträge: 2
Registriert: Freitag 11. Oktober 2019, 12:37

oh vi macht beim coden automatisch whitespaces aus Tabs :D

Und vielen Dank für die schnellen Antworten!!
Antworten