2

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

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

  1. 它不等于除自身之外的任何其他对象。
  2. 除了从原始引用(通过赋值或参数传递)之外,无法创建对它的引用。

None满足第一个但不满足第二个要求(因为它可以通过使用 literal 在程序中的任何位置创建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。)

4

2 回答 2

3

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

于 2012-09-07T05:35:54.167 回答
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 上的对象对其比较语义具有疯狂的攻击性,并且与眼前的一切进行比较,我对此无能为力。可以说,这种攻击性行为几乎是一个错误。这就是为什么我认为这是一个小问题。

于 2012-10-10T20:01:07.440 回答