我正在将一些代码从Python 2迁移到Python 3,并且我得到了不同的行为。查看“改变了什么”的列表并没有指出任何相关的差异,但可能我错过了一个大的。
我尽可能地简化了我的代码以获得这个“最小错误程序”:
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)
此代码运行,并在Python 2.7中打印Constructed example instance
。
此代码失败,并在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
通常这个错误意味着有人拼写错误__init__
(所以构造函数参数绕过相关的类并被赋予object
的无参数构造函数,但似乎并非如此这里。
哦,作为事后的想法,我确认,是的,{2.7}中param
的值为5。
2to3
给它一个清洁的健康状况。
请给我一个指向Python 3中的更改的指针,该更改会使此代码无效,因此我可能会详细了解它。
答案 0 :(得分:2)
你的问题有答案:
通常这个错误意味着[...]构造函数参数被赋予对象的无参数构造函数[...]
要修复此问题,请将您的装饰器更改为仅在传入的__init__
具有这些方法时添加__new__
和Type
。