所以,我今天才意识到__new__
因为接收参数而被弃用了,因为python 2.6(文档中没有提到它,{{1}的行为也是如此。 }据我所知,调用__new__
。这意味着我的功能代码已经开始发出警告,我想摆脱它们。但我看不出一种优雅的解决方法。
我有一堆类在构造时执行优化。所以我有
__init__
等等(真实版本涵盖更多案例)。因此,与Guido在this response中所说的(我能找到的唯一引用)不同,我的class Conjunction(Base):
def __new__(cls, a, b):
if a == True:
return b
elif b == True
return a
else:
return super(Conjunction,cls).__new__(cls, a, b)
方法 使用其参数,不能被覆盖的__new__
函数替换。
我能做的最好的事情就是把它分成两部分:
__init__
但这很丑陋,对天堂很臭。我是否缺少一种优雅的方法让类构造函数根据给定的构造函数参数返回一些任意对象?
答案 0 :(得分:10)
__new__
不是“因接收参数而弃用”。 Python 2.6中的变化是object.__new__
, object 类的__new__
方法,不再忽略它传递的任何参数。 (object.__init__
也不再忽略参数,但这只是2.6中的警告。)如果要将参数传递给{{{},则不能使用object
作为继承的终止类。 1}}或__new__
。
为了使任何代码依赖于该行为在2.6中工作,您只需要将__init__
替换为基类,使用正确接受额外参数的基类并且不在它进行的调用中传递它们(使用object
。)
答案 1 :(得分:5)
托马斯在我的回答中说得对,但我应该补充一点,在我的案例中解决方案是微不足道的:在我的基类中添加一个__new__
方法:
class Base(object):
def __new__(cls, *args, **kws):
instance = super(Base, cls).__new__(cls)
instance.__init__(*args, **kws)
return instance
答案 2 :(得分:0)
这让我很好奇,因为我没有看到文档中的弃用,所以我自己试了一下。
class Foo(object):
def __new__(cls, a, b):
if a:
return a
elif b:
return b
else:
return super(Foo, cls).__new__(cls, a, b)
def __init__(self, a, b):
self.a = a
self.b = b
class Bar(Foo):
def __new__(cls, x, y):
if x:
return x
if y:
return y
else:
return super(Bar, cls).__new__(cls, x, y)
foo = Bar(False, False)
正如您在本示例中所看到的,我在Foo中覆盖了init,因为传递给new的任何args都将转发到__new__
尝试创建的cls实例。 foo的实例是一个Bar类但它有成员a和b。我通过不覆盖超级类__init__
来调用超级类__new__
。方法__init__
始终将其args传递给__init__
。如果你没有覆盖对象的{{1}},它将失败,因为该方法没有args。
这是我在Python 2.7中使用new的看法。根据文档2.6类似。