Reputation: 51
Can someone explain this behavior?
A.py:
import B
values = []
if __name__ == "__main__":
values.append('something')
print(values)
B.printValues()
B.py:
import A
def printValues():
print(A.values)
Result:
['something']
[]
I expected:
['something']
['something']
Upvotes: 4
Views: 199
Reputation: 43296
This is what happens:
A
imports B
. This causes the code in B
to be executed:
A
is imported. Because this is the first time A
is being imported (A
is not in sys.modules
), all the code in A
is executed.
import B
is executed. This does not execute the code in B
, because B
is already in sys.modules
.values
is created.if __name__=='__main__'
block is not executed, leaving values
empty.B
now has a reference to a module A
that differs from the main module. You can confirm this by adding import __main__; print __main__ is A
to B
. It will print False
.Upvotes: 2
Reputation: 12204
Yes, I am pretty sure A as main is not the same as the one in import A which ends up in sys.modules. So A exists twice, once as main, once as a module. Added a third module, C and you see that the B to C semantics meet your expectation - B and C share a common A.
A.py
import sys
print len(sys.modules), "len(sys.modules):A top"
import B, C
print len(sys.modules), "len(sys.modules):A after import B, C"
values = []
if __name__=="__main__":
values.append('something')
print "A:", values, 'id:',id(values)
B.printValues()
C.printValues()
B.py
import sys
print len(sys.modules), "len(sys.modules):B top"
import A
print len(sys.modules), "len(sys.modules):C after A import"
def printValues():
print "B:", A.values, "id:", id(A.values)
C.py
import sys
print len(sys.modules), "len(sys.modules):C top"
import A
print len(sys.modules), "len(sys.modules):C after A import"
def printValues():
print "C:", A.values, "id:", id(A.values)
and this all outputs:
42 len(sys.modules):A top
43 len(sys.modules):B top
44 len(sys.modules):A top
45 len(sys.modules):C top
45 len(sys.modules):C after A import
45 len(sys.modules):A after import B, C
45 len(sys.modules):C after A import
45 len(sys.modules):A after import B, C
A: ['something'] id: 4493313232
B: [] id: 4493269616
C: [] id: 4493269616
Upvotes: 1
Reputation: 388
In short, it is a kind of closure.
you can add print
any place to observe import behavior.
A.py
print("before import B")
import B
print("start execute A as " + __name__)
values = []
if __name__=="__main__":
values.append('something')
print "values=" + str(values)
B.printValues()
B.appendValue("hello")
B.printValues()
print "values=" + str(values)
print("finished execute A as " + __name__)
B.py
print("start runnig B")
import A
def printValues():
print "A.values=" + str(A.values)
def appendValue(new_value):
A.values.append(new_value)
print "A.values=" + str(A.values)
print("finish running B")
it gives result
before import B
start runnig B
before import B
start execute A as A
finished execute A as A
A.values=[]
finish running B
start execute A as __main__
values=['something']
A.values=[]
A.values=['hello']
values=['something']
finished execute A as __main__
A.values
seen from B.py is another instance of data.
It is not A.py's values
. there is another namespace between combination of program & __name__
.
Upvotes: 0