Reputation: 2954
I wonder about why import a variable in python (python 3.4) has different result than importing a module and then referencing, more over why does a deep copy is made - and is there a way to bypass the copy (and not by defining a function that simply returns it)?
a.py
v = 1
def set():
global v
v = 3
main.py
import a
import b
a.set()
b.foo()
b.py
from a import v
def foo():
print(v)
print(a.v)
print(id(v))
print(id(a.v))
Output
1
3
1585041872
1585041904
Upvotes: 2
Views: 2672
Reputation: 771
Asked a duplicate question myself, and with the help of others I figured out what it is. Here's what I found out. With pydoc
links:
from a import v
does not add a reference to a.v
. Instead, it add a new variable to b
as b.v
with the value of a.v
when import
happened. Changing a.v
later does not change the value of b.v
.
The from form does not bind the module name: it goes through the list of identifiers, looks each one of them up in the module found in step (1), and binds the name in the local namespace to the object thus found.
The from form uses a slightly more complex process:
- find the module specified in the
from
clause, loading and initializing it if necessary;- for each of the identifiers specified in the
import
clauses:
- check if the imported module has an attribute by that name
- if not, attempt to import a submodule with that name and then check the imported module again for that attribute
- if the attribute is not found,
ImportError
is raised.- otherwise, a reference to that value is stored in the local namespace, using the name in the as clause if it is present, otherwise using the attribute name
The keyword here is in the local namespace.
Upvotes: 2
Reputation: 3360
When you say import a
, you are creating a reference to the module. a.v is not copied. I change in one module is noticed in all modules. When you say from a import v
you are making a copy of v at the time of the import. If either variable is changed, it is not reflected elsewhere.
Upvotes: 0
Reputation: 34282
Let's examine the sequence of events:
a.v = 1 # a.py: v = 1
b.v = a.v # b.py: from a import v
a.v = 3 # a.set()
print(b.v) # foo(): print(v)
print(a.v) # foo(): print(a.v)
As you can see, from a import v
actually binds b.v
to a value from a
, and later modification to the original variable don't affect the copy.
Upvotes: 1
Reputation: 522210
The problem is that you're modifying a scalar value. This is not a problem specific to modules, it would work the same when simply passing the variable into a function and modifying it there.
The value 1
is imported from a
, period. Whatever you do in a
afterwards will not modify the value, because it's a simple immutable scalar value.
If a.v
was an object, changes to this object would propagate to any variable holding a reference to it.
Upvotes: 3