所以我试图覆盖
__new__
并让它作为工厂存在来创建
派生实例。在阅读了一些关于 SO 的内容之后,我的印象是我也应该在派生实例上调用 __new__
。
基础事物
class BaseThing:
def __init(self, name, **kwargs):
self.name = name
# methods to be derived
事物工厂
class Thing(BaseThing):
def __new__(cls, name, **kwargs):
if name == 'A':
return A.__new__(name, **kwargs)
if name == 'B':
return B.__new__(name, **kwargs)
def __init__(self, *args, **kwargs):
super().__init__(name, **kwargs)
# methods to be implemented by concrete class (same as those in base)
A
class A(BaseThing):
def __init__(self, name, **kwargs):
super().__init__(name, **kwargs)
B
class B(BaseThing):
def __init__(self, name, **kwargs):
super().__init__(name, **kwargs)
我所期待的是它会起作用。
>>> a = Thing('A')
给了我
TypeError: object.__new__(X): X is not a type object (str)
我对此有点困惑;当我只返回派生类的具体实例时,它就起作用了。即
def __new__(cls, name, **kwargs):
if name == 'A':
return A(name)
if name == 'B':
return B(name)
我认为这不是
return
中 __new__
的正确方法;它可能会重复调用__init__
。
当我检查
__new__
中 object
的签名时,似乎是这个:
@staticmethod # known case of __new__
def __new__(cls, *more): # known special case of object.__new__
""" Create and return a new object. See help(type) for accurate signature. """
pass
没想到就是这个;我希望它也带有 args 和 kwargs 。我一定是在这里做错了什么。
在我看来,我需要直接在我的基础中继承对象,但有人可以解释正确的方法吗?
你打错了
__new__
。如果您希望 __new__
创建子类的实例,则不要调用子类的 __new__
;你像往常一样调用超类的 __new__
,但是 将子类作为第一个参数传递给它:
instance = super().__new__(A)
我不能保证这足以解决您的问题,因为您发布的代码不会重现您声称的错误;它还有其他问题,这些问题首先会导致不同的错误(无限递归)。特别是,如果
A
和 B
并不是真正从 Thing
下降,则需要不同的处理。