我正在使用python 2.7,我想使用类创建某种数据结构
问题A:
假设我创建了这个类:
class my_data():
def __init__(self,data1,data2,data3):
self.data1 = data1
self.data2 = data2
self.data3 = data3
Run Code Online (Sandbox Code Playgroud)
之后我创建了一些类的实例,例如
d1 = my_data(1,2,None)
d2 = my_data(4,5,d1)
d3 = my_data(7,8,d2)
Run Code Online (Sandbox Code Playgroud)
如您所见,data3可能是None或实例.到现在为止还挺好.
现在,让我们再次尝试创建一些其他实例(艰难的方式):
d2 = my_data(4,5,d1)
d1 = my_data(1,2,None)
d3 = my_data(7,8,d2)
Run Code Online (Sandbox Code Playgroud)
在这种情况下会发生NameError异常,因为显然在行d2 = my_data(4,5,d1)中,d1尚未定义.
所以,这里有一个问题:我想创建data3应该是None或实例的实例.如果data3为None或现有实例,则没问题.但是如果data3引用了一个未实现的实例,我希望创建该实例.
例如:d2 = my_data(4,5,d1)
如果d1不存在,我想作为虚拟实例启动d1 = my_data(None,None,None),之后,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
Run Code Online (Sandbox Code Playgroud)
问题B:
假设我们以某种方式创建了类的一些实例(d1,d2,d3,...).如何将实例存储在类中的列表中,以便在此类中创建的每个实例都包含在列表中?
类似my_data.my_list()的东西会生成[d1,d2,d3,...]
任何想法将不胜感激
Mar*_*ers 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
Run Code Online (Sandbox Code Playgroud)
现在,您可以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})
Run Code Online (Sandbox Code Playgroud)
因为我们使用的是定点默认值,你还可以设置data3
到None
还有:
>>> d3 = my_data('a', 'b', None)
>>> d3.data3 is None
True
Run Code Online (Sandbox Code Playgroud)
类上的可变列表可以包含所有实例; 只需将列表设置为类属性并将新实例附加到该属性:
_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)
Run Code Online (Sandbox Code Playgroud)
并且您可以列出所有实例my_data.instances
.
请注意,这会创建循环引用,即使您不再在其他任何地方使用它们,也能使实例保持活动状态.如果要阻止此操作,请使用该weakref
模块.