python - 如何在没有 setter 的属性上使用 += 运算符?

标签 python python-3.x

当我在只读属性上使用 += 运算符时,我收到了一个无法设置属性错误我定义了一个 __iadd__() 方法。

我的代码的简化(但可运行)版本:

class Emitter(list):
    def __iadd__(self, other):
        self.append( other )
        return self

class Widget:
    def __init__(self):
        self._on_mouseenter = Emitter()

    @property
    def on_mouseenter(self): return self._on_mouseenter


my_widget = Widget()
my_widget.on_mouseenter += lambda source: print("on_mouseenter!")

最后一行产生错误。如果我将以下行添加到 Widget 的定义中,它就会消失:

@on_mouseenter.setter
def on_mouseenter(self, value): pass

(可在 https://repl.it/EONf/0 运行)

这种行为在两个方面看起来很奇怪。首先,我认为 Python 通过引用传递对象,那么为什么属性必须是可读的呢?其次,我的虚拟二传手怎么会起作用?

最佳答案

__iadd__ 返回要重新绑定(bind)到变量的替换对象。这当然需要一个 setter。

在这种情况下,它起作用是因为您忽略了该集合,但仍将原始对象留在原地,您已经在原地进行了更改。

此行为是必需的,因为某些对象是不可变的,但就地添加仍然适用于它们。

i += 5 将 i 绑定(bind)到的数字加 5,然后将 i 重新绑定(bind)到新的结果数字。也就是说,它完全等同于 i = i + 5,其中有一个赋值。

关于python - 如何在没有 setter 的属性上使用 += 运算符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40409830/

相关文章:

python - 递归未知深度的查询集列表

python - 从 Python 模块内的 sys.path 中的路径读取图像

python - 打印列表的制表符分隔值

python - 通过支持 Python 和 Python3 的 Homebrew 安装 Vim

python - 准备循环中仅匹配的 json 键

python - 将子字符串替换为列表中的项目

python - Mechanize 和 Beautifulsoup httplib.InvalidURL : nonnumeric port: '' (Python) 错误

python - 处理 Python 中的越界/写入 CSV

python - 有没有办法使用伪随机序列或哈希函数模拟队列的 python random.shuffle?

python - 如何使用 python 在 Windows 64 位中调用 32 位 exe?