回答此问题可获得 20 贡献值,回答如果被采纳可获得 50 分。
<p>很常见的一种情况是,类似结构的类型不希望被远程版权持有者修改。在</p>
<p>字符串是一个基本的例子,但这是一个简单的例子,因为它是可以原谅的不可变的——Python甚至不允许对文本字符串进行方法调用之类的事情。在</p>
<p>问题是(在大多数语言中)我们经常有这样的东西,比如<code>(x,y)</code><code>Point</code>类。我们偶尔想独立地改变<code>x</code>和{<cd4>}。一、 例如,从使用的角度来看,一个<code>Point</code>左值应该是可变的(即使副本看不到变化)。在</p>
<p>但Python2.7似乎没有提供任何选项来启用赋值时自动复制。所以这意味着我们实际上必须使我们的<code>Point</code>类不可变,因为不经意的引用会到处被创建(通常是因为有人在将对象传递给其他人之前忘记了克隆对象)。在</p>
<p>不,我对无数的黑客攻击不感兴趣,这些黑客只允许在“创建对象的同时”进行变异,因为这是一个不可伸缩的弱概念。在</p>
<p>这些情况的逻辑结论是,我们需要我们的变异方法来实际修改左值。例如,<code>%=</code>支持这一点。问题是有一个更合理的语法会更好,比如使用<code>__setattr__</code>和/或定义<code>set_x</code>和{<cd10>}方法,如下所示。在</p>
<pre><code>class Point(object):
# Python doesn't have copy-on-assignment, so we must use an immutable
# object to avoid unintended changes by distant copyholders.
def __init__(self, x, y, others=None):
object.__setattr__(self, 'x', x)
object.__setattr__(self, 'y', y)
def __setattr__(self, name, value):
self %= (name, value)
return self # SHOULD modify lvalue (didn't work)
def __repr__(self):
return "(%d %d)" % (self.x, self.y)
def copy(self, x=None, y=None):
if x == None: x = self.x
if y == None: y = self.y
return Point(x, y)
def __eq__ (a,b): return a.x == b.x and a.y == b.y
def __ne__ (a,b): return a.x != b.x or a.y != b.y
def __add__(a,b): return Point(a.x+b.x, a.y+b.y)
def __sub__(a,b): return Point(a.x-b.x, a.y-b.y)
def set_x(a,b): return a.copy(x=b) # SHOULD modify lvalue (didn't work)
def set_y(a,b): return a.copy(y=b) # SHOULD modify lvalue (didn't work)
# This works in Python 2.7. But the syntax is awful.
def __imod__(a,b):
if b[0] == 'x': return a.copy(x=b[1])
elif b[0] == 'y': return a.copy(y=b[1])
else: raise AttributeError, \
"Point has no member '%s'" % b[0]
my_very_long_and_complicated_lvalue_expression = [Point(10,10)] * 4
# modify element 0 via "+=" -- OK
my_very_long_and_complicated_lvalue_expression[0] += Point(1,-1)
# modify element 1 via normal "__set_attr__" -- NOT OK
my_very_long_and_complicated_lvalue_expression[1].x = 9999
# modify element 2 via normal "set_x" -- NOT OK
my_very_long_and_complicated_lvalue_expression[2].set_x(99)
# modify element 3 via goofy "set_x" -- OK
my_very_long_and_complicated_lvalue_expression[3] %='x', 999
print my_very_long_and_complicated_lvalue_expression
</code></pre>
<p>结果是:</p>
^{pr2}$
<p>如您所见,<code>+=</code>和<code>%=</code>工作得很好,但是其他任何东西似乎都不起作用。当然,语言发明者已经为左值修改创建了一个基本的语法,而不仅仅局限于看起来愚蠢的运算符。我就是找不到。请帮忙。在</p>