Python3 global scoping in different modules

雨燕双飞 提交于 2021-02-08 06:44:48

问题


I would like to clarify, how globals from different modules are scoped?

I failed to find relevant documentation for this matter, thus I am relying on observation, but I would like to have some more insight, if my findings are pure implementation coincidence, or if I can trust them?

Testcase:

module_1.py:

global_var1 = 'm1_v1'
global_var2 = 'm1_v2'

def f():
 print('f: {}'.format(global_var1))
 print('f: {}'.format(global_var2))

module_2.py:

import module_1

global_var1 = 'm2_v1'

def g():
 print('g: {}'.format(global_var1))
 print('g: {}'.format(global_var2))

module_1.f()

g()

$ python3 module_2.py

f: m1_v1
f: m1_v2
g: m2_v1
Traceback (most recent call last):
  File "module_2.py", line 11, in <module>
    g()
  File "module_2.py", line 7, in g
    print('g: {}'.format(global_var2))
NameError: name 'global_var2' is not defined

Conclusion:

Thus, my conclusion is that a function will use the globals in this order:

  1. the module where the function is used
  2. the module where the function is defined (EDIT: this is the only answer!)

Globals are not bleeding through from imported modules.

EDIT: Functions imported from other modules bring their module globals like a closure.

Question:

I would like to see some comprehensive documentation on this matter (which I failed to find...).

While testing this out is nice, I have no idea, if this is a freak coincidence, and this behavior should never be trusted, or this is the expected way?

Also, what if a function is somehow imported through a 3rd module? what if the function is a class method? Etc.etc.

If you can't point me to a documentation, but you know a guideline "for sure", I am interested, as well.


I won't go in lengths why and how I want to use this, I am primarily interested to better understand the workings of python. However, if you do know a better solution, given the information at hand, I am interested to see that, as well - it will NOT be accepted as an answer, though.


In case there is a difference between python2 and python3, my main interest is python3, but it is nice to have the info on python2, as well.


回答1:


TLDR: Python uses lexical/static scoping since Python 2.1, including Python 3. (See name resolution and PEP 227)


Lexical scoping means functions only have access to the enclosing scopes in which they are defined, up to their module’s global namespace. Only the builtins are visible in all modules. The global namespace of modules is not shared, and importing or calling a function in another module does not give it access to that namespace.

Some peculiarities worth pointing out:

  • Local/function scopes are defined when the function is parsed. Names are either local, closures/nonlocal, or global.
  • Global/module scopes are mutable. Names can be added, removed or changed at any time.
  • Classes introduce short-lived scopes that are not visible to functions or other classes defined inside them.



回答2:


Each module has its own global scope. Let's look at the second module:

import module_1

global_var1 = 'm2_v1'

def g():
 print('g: {}'.format(global_var1))
 print('g: {}'.format(global_var2))

module_1.f()

g()

Since global_var1 and global_var2 aren't local variables, they are looked up in the global scope. Since module_2.global_var2 isn't defined, you get a NameError.

You would either need to create module_2.global_var2 with something like from module_1 import global_var2, or change the definition of g to

def g():
    print('g: {}'.format(global_var1))
    print('g: {}'.format(module_1.global_var2))

import module_1 only adds one name to the global scope of module_2, that being module_1, which refers to the module object created by the import statement. from module_1 import global_var2 also only adds one name, global_var2, which is initialized to the value of module1.global_var2 (though with the side effect of creating a new module). In this case, module1.global_var2 and module2.globar_var2 are two distinct objects, not two names for the same object.



来源:https://stackoverflow.com/questions/60352980/python3-global-scoping-in-different-modules

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!