Sie verwenden eine ältere Version Python; die Fehlermeldung aktualisiert, da wurde:
>>> object.__new__(testclass1, 56)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object() takes no parameters
Python nur über __init__
nicht unterstützen Argumente beschweren, wenn weder __new__
noch __init__
außer Kraft gesetzt worden ist; z.B. wenn Sie beide von object
erben. testclass1
passt für diesen Fall, nicht, weil es eine __init__
Methode hat.
Dies ist unveränderlich Typen zu unterstützen Implementierung, die für __init__
keine Verwendung haben (die von object
in diesem Fall vererbt werden würde), und änderbare Typen, wo __new__
sollte über, welche Argumente __init__
erwartet nicht kümmern (die normalerweise wäre mehr Argumente).
Siehe issue 1683368 wo Guido van Rossum seine Motivation dafür erklärt.
Die typeobject.c
source code hat folgendes zu sagen:
Sie fragen sich vielleicht, warum nur object.__new__()
über Argumente klagt
wenn object.__init__()
nicht außer Kraft gesetzt wird, und umgekehrt.
Betrachten Sie die Anwendungsfälle:
Wenn weder außer Kraft gesetzt wird, möchten wir Beschwerden über Überschuss (das heißt, irgend) Argumente hören, da ihre Anwesenheit könnte zeigen es einen Fehler gibt.
Wenn ein unveränderlichen Typen definiert, werden wir wahrscheinlich nur __new__()
, außer Kraft zu setzen, da __init__()
zu spät genannt wird, ein unveränderliches Objekt zu initialisieren. Da __new__()
die Signatur für den Typ definiert, wäre es ein Schmerz, __init__()
nur zu außer Kraft zu setzen, damit es sich über übermäßige Argumente beschwert.
Beim Definieren eines änderbaren Typs überschreiben wir wahrscheinlich nur __init__()
. Also hier gilt die umgekehrte Argumentation: Wir wollen __new__()
nicht überschreiben wollen, nur um es von zu beklagen.
Wenn __init__()
außer Kraft gesetzt wird, und die Unterklasse __init__()
object.__init__()
nennt, sollte dieser über überschüssige Argumente zu beklagen; dito für __new__()
.
Anwendungsfälle 2 und 3 machen es unattraktiv für Überschuss Argumente bedingungslos zu überprüfen. Die beste Lösung, die alle vier Verwendung Fällen richtet sich wie folgt: __init__()
beschwert sich über überschüssige Argumente es sei denn, __new__()
wird außer Kraft gesetzt und __init__()
nicht (IOW, wenn __init__()
außer Kraft gesetzt wird oder __new__()
nicht überschrieben) außer Kraft gesetzt; symmetrisch klagt über __new__()
überschüssige Argumente, es sei denn __init__()
außer Kraft gesetzt wird, und ist nicht __new__()
(IOW, wenn __new__()
außer Kraft gesetzt wird, oder __init__()
nicht überschrieben) außer Kraft gesetzt.
Aus Gründen der Abwärtskompatibilität bricht dies jedoch zu viel Code. Daher werden wir in 2.6 warnen über überschüssige Argumente, wenn beide Methoden überschrieben werden; Für alle anderen Fälle verwenden wir die obigen Regeln.
Beachten Sie, dass die .__init__()
Methode selbst wird sich beschweren, immer noch! Wenn Sie eine Instanz erstellen, werden sowohl __new__
als auch __init__
aufgerufen. Ihr Code ruft nur __new__
direkt und macht nicht aufrufen __init__
! Erstellen einer Instanz von testclass1
und testclass3
beide schlägt fehl, wenn Sie in Argumente übergeben:
>>> testclass1(56)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object() takes no parameters
>>> testclass3(56)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: __init__() takes exactly 1 argument (2 given)
Der einzige Unterschied besteht darin, dass für testclass1
es die Standardmethoden für object()
, die für die benutzerdefinierte __init__
stattdessen einen bestimmten Fehler beklagen ist.
Haben Sie [this] (http://hg.python.org/cpython/file/44ed0cd3dc6d/Objects/typeobject.c#l2818) Kommentar zu den Python-Quellen gelesen? Sie haben beschlossen, unter bestimmten Umständen * keinen * Fehler zu melden, um nur eines von "__init__" oder "__new__" zu definieren. Andernfalls müssten Sie sie immer neu definieren, selbst wenn es sich um No-Ops handelt. – Bakuriu
Ich verstehe das nicht: s Ich definierte nur __init__, es braucht keine Argumente (außer offensichtlich selbst), ich übergebe ein Argument an __new__, warum löst es keinen Fehler aus? – ychaouche