正确覆盖 python3 中的 __new__
correctly override __new__ in python3
所以我试图覆盖 __new__
并让它作为工厂存在以创建
派生实例。在阅读了一些关于 SO 的内容之后,我的印象是我也应该在派生实例上调用 __new__
。
BaseThing
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)
一个
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)
我对此有点困惑;当我只是 return 派生 类 的具体实例时,它就起作用了。即
def __new__(cls, name, **kwargs):
if name == 'A':
return A(name)
if name == 'B':
return B(name)
但是我不认为这是在 __new__
中 returning 的正确方法;它可能会重复对 __init__
.
的调用
当我在 object
中检查 __new__
的签名时,似乎是这个:
@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
继承而来,则需要不同的处理方式。
所以我试图覆盖 __new__
并让它作为工厂存在以创建
派生实例。在阅读了一些关于 SO 的内容之后,我的印象是我也应该在派生实例上调用 __new__
。
BaseThing
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)
一个
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)
我对此有点困惑;当我只是 return 派生 类 的具体实例时,它就起作用了。即
def __new__(cls, name, **kwargs):
if name == 'A':
return A(name)
if name == 'B':
return B(name)
但是我不认为这是在 __new__
中 returning 的正确方法;它可能会重复对 __init__
.
当我在 object
中检查 __new__
的签名时,似乎是这个:
@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
继承而来,则需要不同的处理方式。