Python dot-equals (syntax proposal)
Steven D'Aprano
steve at REMOVE-THIS-cybersource.com.au
Sun May 2 06:08:55 EDT 2010
On Sun, 02 May 2010 04:04:11 -0400, Terry Reedy wrote:
> On 5/2/2010 1:05 AM, Alf P. Steinbach wrote:
>> On 02.05.2010 06:06, * Aahz:
>
>>> and sometimes
>>> they rebind the original target to the same object.
>>
>> At the Python level that seems to be an undetectable null-operation.
>
> If you try t=(1,2,3); t[1]+=3, if very much matters that a rebind
> occurs.
>
>> Granted one could see something going on in a machine code or byte code
>> debugger. But making that distinction (doing nothing versus
>> self-assignment) at the Python level seems, to me, to be meaningless.
>
> Please do not confuse things. Augmented *assignment* must be understood
> as assignment. Failure to do so leads (and has lead) newbies into
> confusion, and puzzled posts on this list.
I think that if you think *only* about Python's standard namespaces, self-
assignment is more or less a no-op. I can't think of any way that x = x
could do anything other than use CPU cycles, *if* you limit yourself to
the standard global or function local namespaces.
But if you think about custom namespace types, and item assignment (e.g.
the example you gave with a tuple), the situation becomes different.
Here's a nice example, using Python 3.1:
>>> class B(A): # class A defined elsewhere -- see below.
... x = 1
... x = x
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in B
File "<stdin>", line 4, in __setitem__
TypeError: can't rebind constants
Thus proving that self-assignment is not necessarily a no-op. How did I
make that work? It takes a custom dict and a bit of metaclass magic:
class ConstantNamespace(dict):
def __setitem__(self, key, value):
if key in self:
raise TypeError("can't rebind constants")
super(ConstantNamespace, self).__setitem__(key, value)
class WriteOnceClass(type):
@classmethod
def __prepare__(metacls, name, bases):
return ConstantNamespace()
def __new__(cls, name, bases, classdict):
return type.__new__(cls, name, bases, classdict)
class A(metaclass=WriteOnceClass):
pass
--
Steven
More information about the Python-list
mailing list