一个类可以包含其自身的实例作为数据容器吗?
一个Python类可以包含它自己作为数据容器吗?看起来可能是这样的:
class A:
def __init__(self, val):
self.a = A(val)
self.val = val
aa = A(2)
#this will cause RuntimeError: maximum recursion depth exceeded
我的目的是使用这个类作为一个数据容器,当它被初始化时,里面包含一个自己的副本,这样可以减少深拷贝的操作。它可以用作一个“撤销”链,当需要的时候可以获取初始化时的值。
这样的操作可能吗?
3 个回答
1
好吧,你在self.a里面定义的类也有self.a,而且这样一直循环下去,没有尽头。我不太明白你这样做的目的是什么,但你可以试试下面这样的写法:
class A:
def __init__(self, val, copy = True):
if copy:
self.a = A(val, False)
self.val = val
8
是的,一个类可以包含它自己的一个实例,不过在创建的时候不能直接这样做,原因已经有其他人解释过了。
比如说,这个类就可以做到这一点:
class A:
def __init__(self,value):
self.value=value
def setProperty(self,subvalue):
self.innerInstance=A(subvalue)
然后你可以这样创建它,并设置它内部的那个自己的副本:
>>>OuterInstance=A(123)
>>>OuterInstance.setProperty(456)
你可以用下面的方式来验证它是否成功:
>>>OuterInstance.innerInstance.value
456
8
这个方法行不通,原因已经说过了:
- Python 看到
A(2)
后,会调用A.__init__
。 A.__init__
会再调用A(val)
。A(val)
又会调用A.__init__
。- 回到第2步
我猜你这么做是为了记录 val
的历史值;也就是说,如果你后来决定想把 val
改成 3
,你不想丢掉原来的值 2
。那这样怎么样:
代码
class A( object ):
@property
def val( self ):
return self.history[ -1 ]
@val.setter
def val( self, value ):
self.history.append( value )
def __init__( self, val ):
self.history = [ ]
self.val = val
解释
A( object )
:类现在应该继承自object
。基本上就是这个原因。@property
:这个告诉 Python,每次我们请求A.val
时,它应该调用A.val()
并返回结果。这是一个 装饰器;可以查一下property
这个内置函数,了解更多信息。@val.setter
:这个和上面类似,但它告诉 Python,每次我们尝试给A.val
赋值时,应该调用下面的函数。它不是直接设置A.val
,而是把值添加到历史记录列表中。