【问题标题】:Creating a unique dummy object创建一个唯一的虚拟对象
【发布时间】:2012-09-07 05:32:31
【问题描述】:

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

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

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

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

【问题讨论】:

  • 除了你不是用身份测试,你是在用平等进行测试。使用a[0] is UNINITIALIZED_VALUE。现在,对于实际上没有任何差异的简单对象。但这是事情的原理。 ;-)
  • @LennartRegebro 我添加了一个答案来解决您的评论。

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


【解决方案1】:

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

【讨论】:

  • Thx.. 对于任意属性,我通常使用x = lambda : 0。这样可以吗?
  • 这行得通,但通常我们创建一个派生自 object 的新类,其中包含一个空(即 pass)块并实例化它。
【解决方案2】:

我只是在创建一个答案,因为我需要更多空间来回复 @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 上的对象对其比较语义具有疯狂的攻击性,并且比较等于所见的一切,我对此无能为力。可以说,这种攻击性行为几乎是一个错误。这就是为什么我认为这是一个小问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多