在不可变对象中修改可变对象的Pythonic方式
假设我有一个类,对于外界来说表现为 int,但实际上是一个可变对象,在多个结构中具有固定位置。如果 n 是我的对象,我现在可以通过编写 n.update(34)
来更新它,但我发现我总是想编写 n = 34
。我浏览过 http://docs.python.org/reference/datamodel.html,并且没有看到任何类似 __assign__ 或 __value__ 属性的东西,它们可以让我捕获 =
运算符并允许我更新我的对象,而不是将 int 分配给变量 n,从而丢弃我的对象。更好的是,当一个可变对象位于元组 t = (m, n)
中时,我想用 t[1] = 34
更新我的可变对象,但 Python 认为尝试修改一个不可变的。
所以我想答案是,根据我能理解的那份文档的一小部分,我正在尝试的不是Pythonic。所以如果我不能按照我想要的方式去做,那么下一个最好的事情是什么?这样,如果有一天有人必须维护我的代码,也不会过于冒犯。
let's say I have a class that behaves as an int to the outside world, but in fact is a mutable object that has a fixed place within several structures. if n is my object, I can update it now by writing n.update(34)
, but I find I'm always wanting to write n = 34
instead. I've glanced over http://docs.python.org/reference/datamodel.html, and don't see anything like an __assign__ or __value__ attribute that would let me trap the =
operator and allow me to update my object rather than assign an int to the variable n, throwing my object away. better still, when a mutable is inside a tuple t = (m, n)
, I would like to update my mutable with t[1] = 34
, but Python sees that as attempting to modify an immutable.
so I guess the answer would be, based upon what little of that document I was able to grok, that what I'm attempting is not Pythonic. so if I can't do it the way I want, what would be the next best thing? such that if someone has to maintain my code someday, it won't be overly offensive.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
基本的 obj.value = newvalue 基本上是最好、最容易理解的方法。正如您猜测的那样,不可能覆盖 Python 中的赋值。
您可以在您的类上实现
__call__()
来完成分配,这样您就可以执行obj(newvalue)
。然而,普通读者根本不清楚这是一次重新分配。另一个想法是实现
__ilshift__()
,这样你就可以执行obj <<= newval
。如果你仔细观察的话,这至少看起来像是某种突变体重新分配操作。如果不是数字类型,我可能会考虑。但是<<
对int
具有明确定义的含义,并且由于您伪装成该类型,因此恕我直言,以这种方式使用它会令人困惑。Your basic
obj.value = newvalue
is basically the best, most understandable way. As you surmise, it is not possible to override assignment in Python.You could implement
__call__()
on your class to do the assignment, so that you can just doobj(newvalue)
. However, it's not at all clear to the casual reader that that's a reassignment.Another idea would be to implement
__ilshift__()
so you can doobj <<= newval
. That at least looks like some kind of mutant reassignment operation if you squint hard enough. If it weren't a numeric type, I might consider it. But<<
has a well-defined meaning withint
and, since you're masquerading as that type, it would IMHO be confusing to use it in this way.