的Python:重写__init__ ARGS在__new__

问题描述:

我有一个__new__方法如下:的Python:重写__init__ ARGS在__new__

class MyClass(object): 
    def __new__(cls, *args): 
     new_args = [] 
     args.sort() 
     prev = args.pop(0) 
     while args: 
     next = args.pop(0) 
     if prev.compare(next): 
      prev = prev.combine(next) 
     else: 
      new_args.append(prev) 
      prev = next 
     if some_check(prev): 
      return SomeOtherClass() 
     new_args.append(prev) 
     return super(MyClass, cls).__new__(cls, new_args) 

    def __init__(self, *args): 
     ... 

然而,这种失败并产生警告:

DeprecationWarning: object.__new__() takes no parameters 

SomeOtherClass可以根据需要获取创建为ARG游戏处理,这就是为什么他们正在处理__new__而不是在__init__

什么是最好的方式通过new_args__init__

否则,我将不得不重复args来处理__init__(不some_check)

我到底去解决的办法是修改在__new__新创建的对象,并完全消除__init__方法:通过设计

def __new__(cls, *args): 
    ... # as above 
    new_self = super(MyClass, cls).__new__(cls) 
    new_self.args = new_args 
    return new_self 

#def __init__(self, *args): 
# self.args = args 

既然你甚至不需要创建一个MyClass的对象,为什么不把新成一个单独的函数new(*args)返回必要时使用MyClassSomeOtherClass对象?

由于您知道在任何地方放置MyClass()后都会返回一个MyClass对象,并且可能不会有SomeOtherClass,这可能有点令人困惑。

+0

在我的情况,这是因为MyClass的和SomeOtherClass是合作类型,并可以互换使用(通用界面)。 – EoghanM 2010-03-18 07:55:20

编辑:提出了一个更好的解决方案 - 以下行为不够一致。


我已经跌倒了一些出乎意料的简单行为,解决自己的问题:

return cls(*new_args) 

代替

return super(MyClass, cls).__new__(cls, *new_args) 

它不会进入无限递归,因为我预计,只要new_args__new__的原始参数不一样。