我需要创建一个虚拟对象来标记列表中的未初始化元素(显然,字典本来是一个更好的选择,但由于内存限制很大,我需要一个列表。)
我正在考虑为此目的使用具有以下属性的对象:
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.)
答案 0 :(得分:3)
不,这就是每个人都这样做的方式。请注意,您无法在此类对象上设置任意属性。
答案 1 :(得分:0)
我只是在创建答案,因为我需要更多空间来回复@Lennart Regebro的有趣评论。他的评论让我想到a[0] is UNINITIALIZED_VALUE
或a[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上的对象对其比较语义疯狂地进行攻击,并且比较等同于所看到的一切,我就无法做任何事情。可以说,这种侵略行为几乎是一个错误;这就是为什么我认为这是一个小问题。