Why do directly imported variables behave differently than those attached to imported module?
Chris Rebert
clp2 at rebertia.com
Tue May 3 12:57:53 EDT 2011
On Tue, May 3, 2011 at 9:31 AM, Dun Peal <dunpealer at gmail.com> wrote:
> Hi!
>
> Here's the demonstrating code:
>
> # module foo.py
> var = 0
>
> def set():
> global var
> var = 1
>
> Script using this module:
>
> import foo
> from foo import *
>
> print var, foo.var
> set()
> print var, foo.var
>
> Script output:
>
> 0 0
> 0 1
>
> Apparently, the `var` we imported from `foo` never got set, but
> `foo.var` on the imported `foo` - did. Why?
Because imports (and assignments generally) bind names to values, they
don't alias names to other names.
from foo import *
can be thought of as essentially doing:
import foo
set = foo.set
var = foo.var
del foo
So the new, separate name __main__.var gets the current value of
foo.var at import-time, which is the integer 0.
You then call foo.set(), which re-binds foo.var to a new value (i.e.
1) rather than mutating the existing value (which would be impossible
anyway since integers are immutable). This has absolutely no effect on
__main__.var, which is an entirely separate binding.
The behavior is comparable to that of function arguments. Values can
be mutated, but re-binding names has only local effect:
>>> a = 0
>>> def incr(b):
... b = 1 # rebinds local name b
...
>>> incr(a)
>>> a # outside name unaffected, just like in your example
0
>>> c = [7]
>>> def mutate_then_rebind(b):
... b.append(99) # mutates passed-in value
... b = [42] # rebinds local name; has no outside effect
...
>>> mutate_then_rebind(c)
>>> c # name still references same obj, but that obj has been mutated
[7, 99]
Cheers,
Chris
--
http://rebertia.com
More information about the Python-list
mailing list