我正在使用python 2.7,我想使用类
创建某种数据结构问题A:
让我们说我创建了这个类:
class my_data():
def __init__(self,data1,data2,data3):
self.data1 = data1
self.data2 = data2
self.data3 = data3
然后我创建了一些类的实例,例如
d1 = my_data(1,2,None)
d2 = my_data(4,5,d1)
d3 = my_data(7,8,d2)
如您所见,data3可能是None或实例。到目前为止一切都很好。
现在,让我们再次尝试创建一些其他实例(艰难的方式):
d2 = my_data(4,5,d1)
d1 = my_data(1,2,None)
d3 = my_data(7,8,d2)
在这种情况下会发生NameError异常,因为显然符合要求 d2 = my_data(4,5,d1),d1尚未定义。
所以,问题是:我想创建data3应为None或实例的实例。 如果data3为None或现有实例,则没问题。 但是如果data3引用了一个未显示的实例,我希望创建该实例。
例如:d2 = my_data(4,5,d1)
如果d1不存在,我希望作为虚拟实例启动d1 = my_data(无,无,无),之后,d2也要启动
我试过这个,但似乎没有做到这一点:
class my_data():
def __init__(self,data1,data2,data3):
self.data1 = data1
self.data2 = data2
try:
self.data3 = data3
except:
data3 = my_data(None,None,None)
self.data3 = data3
问题B:
让我们说某种程度上我们已经创建了类的一些实例(d1,d2,d3,...)。如何将实例存储在类中的列表中,以便在此类中创建的每个实例都包含在列表中?
像my_data.my_list()这样的东西 这将产生 [d1,d2,d3,...]任何想法都将受到赞赏
答案 0 :(得分:10)
您无法从不存在的引用中实现对象。 Python名称有存在,以便它们起作用。
相反,请为data3
关键字指定默认值,然后在指定关键字 时,创建实例:
_sentinel = object()
class my_data():
def __init__(self, data1, data2, data3=_sentinel):
if data3 is _sentinel:
data3 = my_data(None, None, None)
self.data1 = data1
self.data2 = data2
self.data3 = data3
现在,您可以使用my_data()
的默认新实例创建data3
的实例:
>>> d2 = my_data('a', 'b')
>>> d1 = d2.data3
>>> d1
<__main__.my_data instance at 0x10e994cf8>
>>> vars(d2), vars(d1)
({'data1': 'a', 'data3': <__main__.my_data instance at 0x10e994cf8>, 'data2': 'b'}, {'data1': None, 'data3': None, 'data2': None})
由于我们使用了哨兵默认值,您仍然可以将data3
设置为None
:
>>> d3 = my_data('a', 'b', None)
>>> d3.data3 is None
True
类上的可变列表可以容纳所有实例;只需将列表设置为类属性并将新实例附加到该属性:
_sentinel = object()
class my_data():
instances = []
def __init__(self, data1, data2, data3=_sentinel):
if data3 is _sentinel:
data3 = my_data(None, None, None)
self.data1 = data1
self.data2 = data2
self.data3 = data3
my_data.instances.append(self)
您可以使用my_data.instances
列出所有实例。
请注意,这会创建循环引用,即使您不再在其他任何地方使用它们,也可以使实例保持活动状态。如果您想阻止此操作,请使用weakref
module。
答案 1 :(得分:0)
您是否考虑过重新设计数据结构和对象?在对象A中创建对象A的实例不是一个好方法。也许你应该将my_data分成两个对象。一个持有两个值,另一个持有相关性和列表。
PS:我强烈怀疑你是使用my_data表示图形,如果是这样的话,请尝试使用 Networkx ,这是一个很好的图形包。