python类:有关创建实例的问题

时间:2013-12-03 10:26:32

标签: python class

我正在使用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,...]

任何想法都将受到赞赏

2 个答案:

答案 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 ,这是一个很好的图形包。