我正在编写一个TreeStructure
(TS)类,它允许我创建相互链接的父对象和子对象。每个TS对象都有m_parent
属性,该属性由parent
属性控制,并且它们还有children
列表,该列表包含在此父级的所有子级中。每当我将一个孩子添加到它的父亲的children
列表中时,它也会被添加到它自己的children
列表中?这就是我所拥有的:
ROOT = "__ROOT__"
class TreeStructure:
def __init__(self, parent=ROOT, children=[]):
self.children = children
self.parent = parent
@property
def parent(self):
'''Returns m_parent'''
if hasattr(self, "m_parent"):
return self.m_parent
else:
return None
@parent.setter
def parent(self, parent=ROOT):
'''Sets m_parent'''
if type(parent) == type(self):
if self.parent:
del self.parent
self.m_parent = parent
self.m_parent.children.append(self)
elif parent == ROOT:
if self.parent:
del self.parent
self.m_parent = ROOT
else:
raise TypeError("Parent's type %s did not match objects type %s"
%(type(parent), type(self)))
@parent.deleter
def parent(self):
'''Deletes m_parent'''
if self.parent:
if self.parent != ROOT:
self.m_parent.children.remove(self)
del self.m_parent
现在通过创建两个简单的对象,它应该可以工作。但是,它没有。
a = TreeStructure()
b = TreeStructure(a)
问题出现在第25行self.m_parent.children.append(self)
。如果我在该行的两边添加print,我会看到print(self.m_parent.children)
和print(self.children)
在追加行之前打印一个空列表[]
。现在,如果我在附加行之后添加打印件,两个打印件都会显示[<__main__.TreeStructure object at 0x...>]
,这应该只发生在父级而不是孩子身上?
答案 0 :(得分:4)
不要将[]
用作默认值!
>>> def bad(default=[]):
... default.append(1)
... print default
...
>>> bad()
[1]
>>> bad()
[1, 1]
>>> bad()
[1, 1, 1]
>>> def good(default=None):
... if default is None:
... default = []
... default.append(1)
... print default
...
>>> good()
[1]
>>> good()
[1]
默认参数是在函数定义时创建的,而不是在调用时创建的。
因此,只能使用非可变类型作为默认值。使用整数,字符串,元组是可以的,但如果你想要一个默认列表或字典或任何可变的东西,那么使用None
并执行上述技巧。
阅读this问题和答案,以便更好地了解此事。
答案 1 :(得分:-2)
您已经被旧式类(不支持描述符,例如@property
)所困扰。你应该使用:
class TreeStructure(object):
完成后,您的代码适合我
我正在使用python 2.7进行测试。在3.x中,所有类都是新式的。