基于this answer,__new__
和__init__
应该如何在Python中运行,
我编写了这段代码来动态定义和创建一个新的类和对象。
class A(object):
def __new__(cls):
class C(cls, B):
pass
self = C()
return self
def foo(self):
print 'foo'
class B(object):
def bar(self):
print 'bar'
a = A()
a.foo()
a.bar()
基本上,因为A的__new__
返回一个继承A和B的动态创建的C,它应该有一个属性bar
。
为什么C
不具有bar
属性?
答案 0 :(得分:7)
由于问题中没有实际的问题,我将从字面上理解:
动态做错了什么?
嗯,对于你的代码的用户来说,它实际上是不可读的,非常不透明和不明显的(包括你在一个月内:P)。
根据我的经验(非常有限,我必须承认,不幸的是,我没有20年的编程),对此类解决方案的需求表明,类结构没有明确定义, - 意味着,差不多总是一个更好,更可读,更不神秘的方式来做这些事情。
例如,如果真的想要动态定义基类,最好使用工厂函数,它将根据您的需要返回适当的类。
另一个问题:
动态做错了什么?
在您当前的实现中,它给出了“超出最大递归深度”错误。发生这种情况,因为A.__new__
无限期地从内部调用自身(因为它从自身和B
继承)。
10:在A.__new__
内,“cls”设置为<class '.A'>
。在构造函数中,您定义了一个类C
,它继承自cls
(实际上是A
)和另一个类B
。实例化C
后,将调用其__new__
。由于它没有定义自己的__new__
,因此调用其基类“__new__
。基类恰好是A
20:GOTO 10
答案 1 :(得分:7)
Resolve无限递归:
class A(object):
def __new__(cls):
class C(cls, B):
pass
self = object.__new__(C)
return self
(感谢balpha指出实际问题。)
答案 2 :(得分:3)
如果你的问题是“我怎样才能做到这一点” - 这有效:
class A(object):
@classmethod
def get_with_B(cls):
class C(B, cls):
pass
return C()
def foo(self):
print 'foo'
class B(object):
def bar(self):
print 'bar'
a = A.get_with_B()
a.foo()
a.bar()
如果您的问题是“为什么它不起作用” - 那是因为当您致电C()
时会遇到无限递归,这导致A.__new__
被调用,再次调用{{1}等等。