【问题标题】:Augmented assignment with frozenset使用 freezeset 的增强分配
【发布时间】:2017-02-05 03:15:07
【问题描述】:

我刚刚在一个frozenset上尝试了一个增强的任务,结果让我很惊讶:

>>> x = frozenset(['foo', 'bar', 'baz'])
>>> x
frozenset({'foo', 'baz', 'bar'})
>>> x &= {'baz', 'qux', 'quux'}
>>> x
frozenset({'baz'})

这不应该发生,是吗? freezesets 不是不可变的吗?

【问题讨论】:

  • 在操作前后检查xid

标签: python set immutability augmented-assignment


【解决方案1】:

你为什么感到惊讶?

您知道“增强分配”这个术语,所以找到"Python Data Model on augmented arithmetic assignments"(强调我的)没有问题:

这些 [__i***__] 方法应该尝试就地执行操作(修改 self)并返回结果(可以是但不一定是 self)。 如果未定义特定方法,则扩充分配回退到普通方法。例如,如果 x 是具有 __iadd__() 方法的类的实例,则 x += y 是相当于 x = x.__iadd__(y) 。否则,考虑x.__add__(y)y.__radd__(x),[...]

>>> x = frozenset(['foo', 'bar', 'baz'])
>>> x.__iand__
[...]
AttributeError: 'frozenset' object has no attribute '__iand__'

所以它没有__iand__ 方法所以你执行的代码是:

>>> x = x & {'baz', 'qux', 'quux'}

__and__ 方法是由 frozenset 定义的:

>>> x & {'baz', 'qux', 'quux'}
frozenset({'baz'})

但是你失去了对原始frozenset的引用:x

>>> y = x   # that doesn't do a copy, it's just to check if `x` has changed"
>>> x &= {'baz', 'qux', 'quux'}
>>> x is y  # check if they reference the same object!
False
>>> x, y
(frozenset({'baz'}), frozenset({'bar', 'baz', 'foo'}))

但这只是在"Principle of least astonishment" 之后。您想要 __and__ 并且明确表示您不想保留原来的 x - 就地操作也会改变它!

再说一遍:为什么这让你感到惊讶?

【讨论】:

    【解决方案2】:

    Frozensets 是不可变的,除了您的赋值不会改变原始的frozenset - 您只是将变量x 重新分配给二元运算符& 的结果。正如 cmets 中的 user2357112 所指出的,在找不到 __iand__ 方法后,x &= {'baz', 'qux', 'quux'} 会退回到 x = x & {'baz', 'qux', 'quux'},从而为您留下非变异操作。

    对于不提供 __iand__ 的不可变类型的其他增强操作,可以看到此行为,例如

    In[1]: x = (1, 2, 3)
    In[2]: id(x)
    Out[2]: 761782862328
    In[3]: x += (4, 5)
    In[4]: id(x)   # we now have a different id
    Out[4]: 761780182888
    In[5]: x[2] = 3  # an actual mutating operation
    TypeError: 'tuple' object does not support item assignment
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-11-14
      • 1970-01-01
      • 2022-08-04
      • 1970-01-01
      • 2017-02-26
      • 2016-11-15
      • 2012-01-05
      相关资源
      最近更新 更多