【问题标题】:python class: questions about creating instancespython 类:关于创建实例的问题
【发布时间】:2013-12-03 20:17:14
【问题描述】:

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

问题 B:

假设我们以某种方式创建了类的一些实例 (d1,d2,d3,...)。如何将实例存储在类内的列表中,以便在该类中创建的每个实例都包含在列表中?

类似 my_data.my_list() 这将产生 [d1, d2, d3, ...]

任何想法将不胜感激

【问题讨论】:

  • my_data 构造函数未传递名称 d1。它传递了变量d1 所引用的对象。如果d1 没有引用任何内容,则NameError 会在构造函数对其执行任何操作之前发生。

标签: python class


【解决方案1】:

您不能从不存在的引用中具体化对象。 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

现在您可以使用data3 的默认新实例创建my_data() 的实例:

>>> 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

【讨论】:

    【解决方案2】:

    您有没有想过重新设计您的数据结构和对象?在对象 A 中创建对象 A 的实例不是一个好方法。也许你应该把 my_data 分成两个对象。一个保存两个值,另一个保存关系和列表。

    PS:我强烈怀疑您使用 my_data 表示图形,如果是这样,请尝试 Networkx,这是一个很好的图形数据包。

    【讨论】:

    • 实际上我确实想使用networkx来表示一个由管道组成的水力网络。每个管道都应该是一个节点,通过边缘与其他管道连接。每个对象管道都应该像管道(ID ,length,flow,parent)。主要目标是找到一种巧妙的方法从 txt 文件中插入随机排序的数据: ID_1,length_1,flow_1,parent_1(integer,float,float,integer or string) ID_2,length_2,flow_2 ,parent_2 (每个组代表一个管道)...以某种方式将 parent_1,parent_2,... 从整数转换为对象管道,最后用 networkx 下的所有数据生成树
    猜你喜欢
    • 2017-08-27
    • 1970-01-01
    • 2020-06-02
    • 2018-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-09
    相关资源
    最近更新 更多