问题描述
所以我试图覆盖__new__
并将其作为工厂存在以进行创建派生实例.在对SO有所了解之后,我觉得我也应该在派生实例上调用__new__
.
So I am trying to override __new__
and let it exist as a factory to createderived instances. After reading a bit on SO, I am under the impression that I should be calling __new__
on the derived instance as well.
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)
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)
我对此感到困惑;当我只返回派生类的具体实例时,它就起作用了.即
I am bit confused by this; when I just return a concrete instance of derived classes, it just worked. i.e.
def __new__(cls, name, **kwargs):
if name == 'A':
return A(name)
if name == 'B':
return B(name)
但是我不认为这是返回__new__
的正确方法;可能会将呼叫复制到__init__
.
I however don't think this it the correct way of returning in __new__
; it may duplicate the calls to __init__
.
当我在object
中检查__new__
的签名时,似乎是这样的:
when I am checking signatures of __new__
in object
it seems be this one:
@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.我一定在这里做错了.
I didn't expect this was the one; I'd expect it came with args and kwargs as well. I must have done something wrong here.
在我看来,我需要直接在我的基础中继承对象,但是有人可以解释这样做的正确方法吗?
it seems to me that I need to inherit object directly in my base but could anyone explain the correct way of doing it?
推荐答案
您在呼叫__new__
错误.如果要__new__
创建子类的实例,则不要调用子类的__new__
;您可以照常调用超类的__new__
,但是将其传递给子类作为第一个参数:
You're calling __new__
wrong. If you want your __new__
to create an instance of a subclass, you don't call the subclass's __new__
; you call the superclass's __new__
as usual, but pass it the subclass as the first argument:
instance = super().__new__(A)
我不能保证这足以解决您的问题,因为您发布的代码不会重现您声明的错误;它还有其他会首先导致不同错误的问题(无限递归).特别是,如果A
和B
并不是真正地从Thing
衍生而来,则需要不同的处理方式.
I can't guarantee that this will be enough to fix your problems, since the code you've posted wouldn't reproduce the error you claim; it has other problems that would have caused a different error first (infinite recursion). Particularly, if A
and B
don't really descend from Thing
, that needs different handling.
这篇关于正确覆盖python3中的__new__的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!