所以我尝试覆盖__new__
并让它作为工厂存在来创建
派生实例。在阅读了SO之后,我的印象是我应该在派生实例上调用__new__
。
BaseThing
class BaseThing:
def __init(self, name, **kwargs):
self.name = name
# methods to be derived
ThingFactory
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)
乙
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)
但我认为这不是__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。我一定做错了。
在我看来,我需要直接在我的基地继承对象,但有人能解释这样做的正确方法吗?
答案 0 :(得分:1)
您正在调用__new__
错误。如果您希望__new__
创建子类的实例,则不要调用子类__new__
;你像往常一样调用超类__new__
,但将子类作为第一个参数传递给它:
instance = super().__new__(A)
我无法保证这足以解决您的问题,因为您发布的代码无法重现您声称的错误;它有其他问题会导致首先出现不同的错误(无限递归)。特别是,如果A
和B
并非真正来自Thing
,则需要进行不同的处理。