Python3 globals() and locals() contents
在我的python3学习中,在尝试globals()和locals()的同时,我制作了一个非常基本的、独立的python程序,并收到了一些结果,我需要专家的解释。
然后,我在我的python程序(any)中执行了相同的2个函数,并收到了许多(all?)的列表。我的程序中的值,无论它是声明为本地、全局还是非。我的理解是globals()函数包含声明为globals的所有值的列表(对于局部变量也是如此),但是根据我的观察,结果显示出了一些不同的东西。有人能解释我所看到的和为什么吗?下面是程序和结果:
python程序:
1 2 | print("Globals=",globals()) print("Locals=",locals()) |
结果(对于上述两行程序):
1 2 3 4 5 6 7 8 9 10 | =============== RESTART: /home/pi/Junk/globals_locals_test.py ========== Globals= {'__package__': None, '__spec__': None, '__loader__': <class ' _frozen_importlib.BuiltinImporter'>, '__doc__': None, '__file__': ' /home/pi/Junk/globals_locals_test.py', '__builtins__': <module 'builtins' (built-in)>, '__name__': '__main__'} Locals= {'__package__': None, '__spec__': None, '__loader__': <class ' _frozen_importlib.BuiltinImporter'>, '__doc__': None, '__file__': ' /home/pi/Junk/globals_locals_test.py', '__builtins__': <module 'builtins' (built-in)>, '__name__': '__main__'} >>> |
号
简单的解释
设置变量只会更改
这里举个例子
默认情况下,模块作用域全局变量与局部变量的dict相同:
1 2 | >>> globals() is locals() True |
在这种情况下,全局是局部的,修改局部也将修改全局。
如果您创建一个函数并查看其中的局部变量,您将看到局部变量将不同
1 2 3 4 5 6 7 8 | >>> def test(): ... print("globals is locals:", globals() is locals()) ... print("globals:", globals()) ... print("locals:", locals()) >>> test() globals is locals: False globals: {'__name__': '__main__', ...} locals: {} |
号
当您更改函数局部变量时,局部变量将自动更新
1 2 3 4 5 6 7 | >>> def test2(): ... print("locals 1:", locals()) ... x = 1 ... print("locals 2:", locals()) >>> test2() locals 1: {} locals 2: {'x': 1} |
创建新类时也会发生类似的情况
1 2 3 | >>> class Test: ... print("locals:", locals()) locals: {'__module__': '__main__', '__qualname__': 'Test'} |
。更深入的解释
如果你想知道为什么全球人和当地人都是这样,让我们看看在Python的引擎盖下会发生什么。
一些地面工程
所有python代码都会在某个时刻传递等同于
函数
python shell做什么?
如果你愿意的话
1 | >>> print(globals()) |
repl将在内部执行以下操作:
1 2 3 4 5 6 7 8 9 | # This variable stores your globals. _my_main_module = {} def exec_some_line(line): return eval(line, globals=_my_main_module, locals=_my_main_module) # ... exec_some_line("print(globals())") |
。
如您所见,python shell将在某个时刻将
函数执行
在内部,函数执行基本上要做三件事:
这里是一个伪算法:
1 2 3 4 | def __call__(*args, **kwargs): local_variables = parse_signature_with_args(args, kwargs) exec(function_source, function_globals, local_variables) return function_result |
。
创建新类
使用class语句时,所有缩进代码都将单独执行。
如果执行此代码:
1 2 | class Test: a = 5 |
这大概是发生的事情:
1 2 3 4 5 6 7 8 9 10 | # 1. A new dictionary is created _dict = type.__prepare__() _dict["__module__"] = __name__ _dict["__qualname__"] ="Test" # 2. Execute the code exec("a = 5", globals=globals(), locals=_dict) # 3. A class is created Test = type("Test", (), _dict) |
。
如何映射到模块导入
如果导入模块,则会启动复杂的导入机制。这是一个简单的概述:
它的工作原理如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | import sys from types import ModuleType def __import__(name): # 1. See if module is already imported if name in sys.modules: return sys.modules[name] # 2. Find file. filename = find_out_path_to_file(name) # 3. Read and parse file with open(filename) as f: script = f.read() # 4. Create the new module module = ModuleType(name) # 5. Execute the code of the module. exec(script, globals=module.__dict__, locals=module.__dict__) # 6. Return the new module. return module |