[Python-ideas] New __reference__ hook
Steven D'Aprano
steve at pearwood.info
Tue Dec 4 12:14:44 CET 2012
On 04/12/12 20:58, haael at interia.pl wrote:
>
> Hi, guys.
>
> Python 3 is very close to become a holy grail of programming languages in
> the sense that almost everything could be redefined. However, there is
>still one thing missing: the immutable copy-on-assign numeric types.
> Consider this part of code:
I dispute that "everything can be redefined" is the holy grail of
programming languages. If it were, why isn't everyone using Forth?
> a = 1
> b = a
> a += 1
> assert a == b + 1
>
> The object "1" gets assigned to the "a" variable,
Correct, for some definition of "assigned" and "variable".
> then another independent copy gets assigned to the "b" variable,
Completely, utterly wrong.
>then the value in the "a" variable gets modified
Incorrect.
> without affecting the second.
> The problem is - this behaviour can not be recreated in user-defined
> classes:
Of course it can.
py> from decimal import Decimal # A pure-Python class, prior to Python 3.3
py> a = Decimal(1)
py> b = a
py> a += 1
py> assert a == b + 1
py> print a, b
2 1
If you prefer another example, use fractions.Fraction, also pure Python
and immutable, with support for augmented assignment.
I don't mean to be rude, or dismissive, but this is pretty basic Python
stuff. Please start with the Python data and execution models:
http://docs.python.org/2/reference/datamodel.html
http://docs.python.org/2/reference/executionmodel.html
although I must admit I don't find either of them especially clear. But
in simple terms, you need to reset your thinking: your assumptions about
what Python does are incorrect.
When you say:
a = 1
you are *binding* the name "a" to the object 1. When you then follow by
saying:
b = a
you bind the name "b" to the *same* object 1. It is not a copy. It is not
a "copy on assignment" or any other clever trick. You can prove to
yourself that they are the same object:
py> a = 1
py> b = a
py> a is b
True
py> id(a), id(b)
(140087472, 140087472)
When you then call
a += 1
this does not modify anything. Int objects (and floats, Decimal, strings,
and many others) are *immutable* -- they cannot be modified. So `a += 1`
creates a new object, 2, and binds it to the name "a". But the binding
from object 1 to name "b" is not touched.
If this is still not clear, I recommend you take the discussion onto one
of the other Python mailing lists, especially tutor at python.org or
python-list at python.org, which are more appropriate for discussing these
things.
--
Steven
More information about the Python-ideas
mailing list