4 ms·
Well, your first example makes sense. It ensures you're always referring to the same-scoped 'a' throughout your function. FWIW if you said 'global a' at the sta
by kbd 15y ago
Well, your first example makes sense. It ensures you're always referring to the same-scoped 'a' throughout your function. FWIW if you said 'global a' at the start of 'print_and_assign_a', Python wouldn't have a problem:
>>> a = 5
>>> def print_and_assign_a():
... global a
... print(a)
... a = 2
...
>>> print_and_assign_a()
5
>>> print_and_assign_a()
2
Your second example, however, seems to show an implementation detail of Python leaking out, and is probably a bug. Union starts off by making a copy of 'a' and adds the elements of 'b' to it, rather than creating a new object and adding the elements of both.
On a hunch that PyPy's implementation would be less special-cased, I installed PyPy and and it actually does print "Init!" on "c = a | b". So, I vote bug in CPython rather than an inconsistency in the language.
One more question arises, however. Should "a = set([1,2])" be equivalent to "a = set(); a.add(1); a.add(2)"? I overloaded 'add' on your PrintOnInitSet and it's not:
>>>> a = PrintOnInitSet(); a.add(1); a.add(2)
init!
Called add with item: 1
Called add with item: 2
>>>> a = PrintOnInitSet([1,2])
init!
- anonymoushn 15y agoThe 'print_and_assign_a' case comes up more often with a in an enclosing local scope, so you couldn't really get it to work prior to the introduction of 'nonlocal' in Python 3. The best you could do was something silly like a = [5] def print_and_assign_a(): print(a[0]) a[0]=2 It's cool that the second case works in other implementations. I hadn't thought to test that.
- kbd 15y agoYes, 'nonlocal' definitely closed a hole in the language.
- ak217 15y ago> Should "a = set([1,2])" be equivalent to "a = set(); a.add(1); a.add(2)"? Why should it be? Adding elements one-by-one is slow and shouldn't be forced on the language model level.