+ 1

Confusion with imports and data access

I defined a class C that had only one method f: print a global variable x. Then I saved this as a module m and imported it. When I typed m.C().f(), I expected that x from the module to be printed, and I was not disappointed. Then I tried to import just the class C and defined another x locally in __main__. When I typed C().f(), I expected my local x to be printed, but instead the x from the module was printed although I only imported C! Can someone explain, what happened there and how it works?

29th Dec 2018, 4:14 PM
HonFu
HonFu - avatar
6 Respostas
+ 6
Python executes your module when you import it. If Python didn't execute it, you'd get an error if you call a function that calls another function https://stackoverflow.com/q/6523791/9132046 Try running this: #module.py print("Hello World") def f(): print("function") #main.py from module import f
29th Dec 2018, 5:13 PM
Mert Yazıcı
Mert Yazıcı - avatar
+ 6
I found this at https://github.com/JUMP_LINK__&&__python__&&__JUMP_LINK/cpython/blob/master/Doc/reference/import.rst """ parent/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py Importing parent.one will implicitly execute parent/__init__.py and parent/one/__init__.py. Subsequent imports of parent.two or parent.three will execute parent/two/__init__.py and parent/three/__init__.py respectively. """ so probably something like this happens when you import something from a module if you want to print local "x" you can do something like this: import __main__ def f(): if __name__ != '__main__': print(__main__.x) else: print(x) if __name__ == '__main__': x = 3 f()
29th Dec 2018, 6:47 PM
Mert Yazıcı
Mert Yazıcı - avatar
+ 1
Okay, I can see now that the module must be run so that the definitions can be executed. And if x was a keyword-argument, I'd understand: These are evaluated once with definition, so when the class gets defined in the module, they would be too. But the print(x) was inside the method f, and the code of f should only be run (and thereby x accessed) when f is actually called, right? 1.) So I import the module. 2.) Then I define a global x. 3.) Then I call the method. Still the method accesses that other x from the module that doesn't even have a name in my __main__ instance! Does this mean that even if I import only a single item from a module using 'from', a separate module namespace is generated anyway and my import will fetch its stuff from there even though I can't access this namespace anymore?
29th Dec 2018, 5:32 PM
HonFu
HonFu - avatar
+ 1
Does that mean, while main imports m, m runs and imports main right back? ^^ Could you even create an import battle between modules and reach ImportBattleRecursionError? Okay, if the reverse import works, it will solve the issue practically; it still doesn't seem to clarify what happens to the module! I am wondering: Okay, the module gets run once, then disappears out of (main globals's) scope, because it is not bound. But although there is no name, the module, invisible to us, must still be there: C.f, lonely protector of the address, continues to reference x, so it can't be collected. And is only x preserved or the whole module object with it, until C dies, with it f and consequentially x, making m garbage-collectable? That would make 'from' imports rather unimpressing. I always imported only what I needed, hoping it would be efficient; but if the stuff is run anyway and possibly even preserved, what would be the point?
29th Dec 2018, 7:29 PM
HonFu
HonFu - avatar
+ 1
Kishalaya Saha just showed me this: https://softwareengineering.stackexchange.com/questions/187403/import-module-vs-from-module-import-function So it seems to be as suspected: The module is there, we just can't point to it!
29th Dec 2018, 8:01 PM
HonFu
HonFu - avatar
+ 1
Python is very famous language.
2nd Jan 2019, 1:05 PM
M.E.S