Ein Fehler wird ausgelöst, wenn ich den Wert eines Arguments einer Klasse festlegen, die von str
erbt. Der Fehler tritt nur auf, wenn ich versuche, mit myClass(arg = 'test')
auf das Argument zuzugreifen. Der Fehler ist:Legen Sie den Wert eines Arguments in einer Klasse fest, die von int oder float oder str erbt
TypeError: 'arg' is an invalid keyword argument for this function
Das Problem wird in diesem exemple gezeigt:
class A(str):
def __init__(self, arg):
pass
A("test") # Works well
A(arg = "test") # Fails
Nur die letzte Zeile der Fehler auslöst. Die vorherige Zeile funktioniert gut. Das Problem ist dasselbe mit Klassen, die von int
oder float
erben.
UPDATE (Lösung):
fand ich eine Lösung mit diesen Links:
- Adding optional parameters to the constructors of multiply-inheriting subclasses of built-in types?
- inheritance from str or int
Die Lösung lautet:
class A(str):
def __new__(cls, *args, **kwargs):
return str.__new__(cls)
def __init__(self, arg01):
print(arg01)
A(arg01= "test")
Ich weiß nicht genau, warum das funktioniert und ich werde es untersuchen. Wenn jemand eine klare Erklärung hat, bin ich interessiert und ich danke ihm im Voraus.
UPDATE (meine Erklärung):
Ich bin überhaupt nicht sicher, was ich will sagen, aber das ist, was ich verstanden.
Stellen Sie sich eine Klasse 'myClass'
ohne irgendeine Vererbung vor. Wenn ich dies tun myInstance = myClass()
, passiert Folgendes:
Die Methode myClass.__new__
wird ausgeführt. Diese Methode erstellt das Objekt myInstance
. __new__
ist der echte Konstruktor (__init__
ist kein Konstruktor!). In Pseudo-Code, schauen __new__
etwas wie folgt aus:
def __new__ (cls, *args, **kwargs):
myInstance = # Do some stuff to create myInstance, an object of the type passed as argument (cls).
# Add the method __init__ to myInstance.
# Call __init__ and pass to it the list 'args' and the dictionary 'kwargs' (both come from arguments of __new__). Pass to it also the object itself (self) :
obj.__init__(self, args, kwargs) :
# Do some stuff.
Die Situation ist ein wenig anders, wenn wir unveränderliche Typen verwenden (str, int, float, Tupel). Im vorherigen Pseudocode habe ich def __new__(cls, *args, **kwargs)
geschrieben. Bei unveränderlichen Typen ist der Pseudocode für die Methode __new__
eher def __new__(cls, anUniqueValue)
. Ich verstehe nicht wirklich, warum das Verhalten von immutableTypes.__new__
von anderen abweicht, aber es ist der Fall. Sie können es in diesem exemple sehen:
class foo():
def __init__(self):
pass
foo.__new__(foo, arg = 1)
# That works because the method __new__ look like this : def __new__(*args, **kargs).
str.__new__(str, arg = 1)
# That fails because we are trying to pass the attribute 'arg' to a method which look like this : def __new__(anUniqueValue).
Von dort aus können wir verstehen, warum die Lösung früheren Arbeiten präsentiert. Was wir tun, ist die Bearbeitung der Methode __new__
eines unveränderlichen Typs, der genau wie ein veränderbarer Typ funktioniert.
def __new__(cls, *args, **kwargs):
return str.__new__(cls)
Diese 2 Zeilen konvertieren def __new__ (cls, anUniqueValue)
zu def __new__ (cls, *args, **kwargs)
ich meine Erklärung hoffen fast klar und ohne so viel Fehler.Wenn Sie Französisch sprechen, können Sie mehr über diesen Link erfahren: http://sametmax.com/la-difference-entre-new-et-init-en-python/
Möglicherweise im Zusammenhang mit http://StackOverflow.com/Questions/3748635/Adding-optional-Parameters-to-the-Constructors-of-multiply-inheriting-subclasses, obwohl ich nicht sicher bin, was Alex Martelli genau durch " ebenso willkürliche Oberklasse '. – timgeb
@Morgan, die Erklärung ist in der verknüpften Frage, kann es auch eine * sie *, die Sie mit einer klaren Erklärung bieten können;) –
@Morgan zögern Sie nicht, Ihre eigene Frage zu beantworten, wenn Sie herausgefunden haben, was genau geht auf. Ich habe die Erklärungen in den verlinkten Fragen nicht vollständig verstanden. – timgeb