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

use*_*854 2 python class

我正在使用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)

因为我们使用的是定点默认值,你还可以设置data3None还有:

>>> 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模块.