2014-10-30 9 views
6

Ich migriere etwas Code von Python 2 nach Python 3, und ich bekomme ein anderes Verhalten. Ein Blick durch die Listen "Was hat sich geändert?" Hat mich nicht auf relevante Unterschiede hingewiesen, aber vermutlich habe ich einen großen vermisst.TypeError: object() nimmt keine Parameter - aber nur in Python 3

Ich habe meinen Code so weit wie möglich vereinfacht diese 'minimal fehlerhafte Programm' zu bekommen:

def decorator(Type): 
    """ This is a class decorator. It replaces a class with a subclass which 
    *should be* equivalent. 

    The result works on Python 2.7 but not on Python 3.4. """ 

    class FactorySubclass(Type): 
     """ This subclasses from the provided type, and overrides the __new__ 
      and __init__ methods, but replaces them with exact equivalents, 
      so I can't see how this has any effect. """ 

     def __new__(cls, *args, **kwargs): 
      # Simplified this code to do basically nothing. 
      # If this line is removed, it works on both versions. 
      return Type.__new__(cls, *args, **kwargs) 

     def __init__(self, *args, **kwargs): 
      # Simplified this code to do basically nothing. 
      Type.__init__(self, *args, **kwargs) 

    return FactorySubclass 


@decorator 
class ExampleClass(object): 
    def __init__(self, param=3): 
     print("Constructed example instance") 


ec = ExampleClass(param=5) 

Dieser Code ausgeführt wird, und druckt Constructed example instance in Python 2.7. Dieser Code schlägt fehl und speichert einen Stack-Trace in Python 3.4.

Traceback (most recent call last): 
    File "mfp.py", line 31, in <module> 
    ec = ExampleClass(param=5) 
    File "mfp.py", line 16, in __new__ 
    return Type.__new__(cls, *args, **kwargs) 
TypeError: object() takes no parameters 

Normalerweise bedeutet dieser Fehler, dass jemand falsch geschrieben hat __init__ (und so Konstruktor Parameter werden die entsprechende Klasse zu umgehen und wird zu object ‚s parameterlosen Konstruktor gegeben, aber das scheint nicht hier der Fall zu sein.

Oh, und wie ein nachträglicher Einfall, bestätigte ich, dass, ja, wird der Wert von param 5 in Python war 2.7.

2to3 gibt es eine saubere Rechnung der Gesundheit.

Bitte geben Sie mir einen Hinweis auf eine Änderung in Python 3, die diesen Code ungültig machen würde, damit ich mehr darüber lesen kann.

+0

Das sieht aus wie ein Betrogen von [Warum funktioniert Objekt. \ _ \ _ New \ _ \ _ anders in diesen drei Fällen] (http://Stackoverflow.com/q/19277399), werde ich untersuchen. –

+0

Ja, dies wird dadurch verursacht, dass 'ExampleClass' keine eigene' __new__' Methode hat. –

+0

mögliches Duplikat von [Warum funktioniert das Objekt. \ _ \ _ New \ _ \ _ in diesen drei Fällen anders?] (Http://stackoverflow.com/questions/19277399/why-does-object-new-work-differently-in) (These-three-cases) –

Antwort

2

Sie haben die Antwort in Ihrer Frage:

Typically this error means [...] constructor parameters are [...] being given to object's parameterless constructor [...]

zu beheben, Ihre Dekorateur nur ändern __init__ und __new__ wenn die übergebenen in Type dieser Methoden hat hinzuzufügen.