Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Cyclic reference
#1
Hi, today i came across this code:

#test1.py 
x=1
def change(): 
    import test1 
    test1.x=2 
change() 
print(x)
output is:
2
1
I want to ask why this doesn't make a cyclic reference, since change function import a module have the function itself. And also, it's output should be 1,2 instead of 2,1 right ?
Reply
#2
Quote:I want to ask why this doesn't make a cyclic reference, since change function import a module have the function itself.
A module will only be imported once and is then stored in a cache (sys.modules). Subsequent import statements will just get the cached module object.

Quote:And also, it's output should be 1,2 instead of 2,1 right ?
print(x) is the last statement in the file, it will be executed last.
import test1 is called before, so the imported module will finish executing before the print in the importing file is reached.
It is worth noting that x and test1.x are two distinct variables.
Reply
#3
Again, when you run the code from the command line as
python test1.py
The code is compiled and ran in a module which name is not 'test1' but '__main__' because it is the main script. Then when the code calls change(), this function runs import test1. This causes the file to be read again because the filename is test1.py, the code is ran again in a new module which name is 'test1'. So there are now two modules with the same code and there are two 'x' variables.

The 'import test1' statement triggers a call to the new function change() from module test1. This call sets test1.x to the value 2 and prints x. Then the 'import test1' is completed and the first call to __main__.change() can complete, but it doesn't change __main__.x which value is still 1, so the last print statement prints 1.

Here is a modified code to show the different steps
#test1.py 
x=1
def change(): 
    print("Entering change() in module", __name__)
    import test1 
    test1.x=2 
    print("Exiting change() in module", __name__)
change()
print("Printing x in module", __name__)
print(x)
Output:
λ python3 test1.py Entering change() in module __main__ Entering change() in module test1 Exiting change() in module test1 Printing x in module test1 2 Exiting change() in module __main__ Printing x in module __main__ 1
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Pass by object reference when does it behave like pass by value or reference? mczarnek 2 2,513 Sep-07-2020, 08:02 AM
Last Post: perfringo

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020