创建一个独特的虚拟对象

时间:2012-09-07 05:32:31

标签: python python-3.x constants identity initialization

我需要创建一个虚拟对象来标记列表中的未初始化元素(显然,字典本来是一个更好的选择,但由于内存限制很大,我需要一个列表。)

我正在考虑为此目的使用具有以下属性的对象:

  1. 它的评估不等于任何其他对象,而是自身。
  2. 除了原始参考(通过赋值或参数传递)之外,不能创建对它的引用。
  3. None满足第一个但不是第二个要求(因为它可以使用文字None在程序中的任何位置创建)。

    我认为应采取的一种方法是:

      UNINITIALIZED_VALUE = object() # will be compared for == through identity
      a = [1, UNINITIALIZED_VALUE, 2, UNINITIALIZED_VALUE]
      a[1] == a[3] # True
      a[0] == UNINITIALIZED_VALUE # False
    

    我想仔细检查一下,我没有错过这种方法的任何潜在问题。 (我正在使用Python 3.)

2 个答案:

答案 0 :(得分:3)

不,这就是每个人都这样做的方式。请注意,您无法在此类对象上设置任意属性。

答案 1 :(得分:0)

我只是在创建答案,因为我需要更多空间来回复@Lennart Regebro的有趣评论。他的评论让我想到a[0] is UNINITIALIZED_VALUEa[0] == UNINITIALIZED_VALUE是否更合适。

我认为由我(设计UNINITIALIZED_VALUE的开发人员)是否承诺支持is==或两者兼而有之。毕竟,除非给出明确的承诺,否则用户不应该做任何事情(因为如果他依赖于未记录的行为,则实现可能会改变并破坏他的代码)。

我实际上认为如果我(作为设计师)承诺is==将会用于测试值是否未初始化会更好。如果不支持==,用户将无法编写如下内容:

def remove_duplicates(list_):
  return list(set(list_)) # requires that UNINITIALIZED_VALUE supports == 

只有一个小问题。作为UNINITIALIZED_VALUE的设计者,当我在LHS(我的原始单行实现)时,我可以很容易地保证它与==的行为正确。但是,我不能保证它在RHS上的行为正确。毕竟,如果LHS上的对象对其比较语义疯狂地进行攻击,并且比较等同于所看到的一切,我就无法做任何事情。可以说,这种侵略行为几乎是一个错误;这就是为什么我认为这是一个小问题。