stu*_*ash 2 python oop inheritance factory-pattern python-3.5
所以我试图覆盖__new__并让它作为一个工厂存在来创建派生实例。在阅读了一些关于 SO 的内容后,我的印象是我也应该调用__new__派生实例。
基础事物
class BaseThing:
def __init(self, name, **kwargs):
self.name = name
# methods to be derived
Run Code Online (Sandbox Code Playgroud)
物厂
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)
Run Code Online (Sandbox Code Playgroud)
一种
class A(BaseThing):
def __init__(self, name, **kwargs):
super().__init__(name, **kwargs)
Run Code Online (Sandbox Code Playgroud)
乙
class B(BaseThing):
def __init__(self, name, **kwargs):
super().__init__(name, **kwargs)
Run Code Online (Sandbox Code Playgroud)
我期待的是它会起作用。
>>> a = Thing('A')
Run Code Online (Sandbox Code Playgroud)
给我 TypeError: object.__new__(X): X is not a type object (str)
我对此有点困惑;当我只返回派生类的具体实例时,它就起作用了。IE
def __new__(cls, name, **kwargs):
if name == 'A':
return A(name)
if name == 'B':
return B(name)
Run Code Online (Sandbox Code Playgroud)
然而,我不认为这是返回的正确方式__new__;它可能会重复调用__init__.
当我检查__new__in 的签名时,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
Run Code Online (Sandbox Code Playgroud)
我没想到是这样;我希望它也带有 args 和 kwargs。我一定在这里做错了什么。
在我看来,我需要直接在我的基地中继承对象,但谁能解释一下正确的做法?
你__new__打错了。如果您希望__new__创建子类的实例,则不要调用子类的__new__; 您__new__像往常一样调用超类,但将子类作为第一个参数传递给它:
instance = super().__new__(A)
Run Code Online (Sandbox Code Playgroud)
我不能保证这足以解决您的问题,因为您发布的代码不会重现您声称的错误;它还有其他问题会首先导致不同的错误(无限递归)。特别是,如果A并且B不真正从 下降Thing,则需要不同的处理。