今天我写了一个"别名导入功能"对我自己来说,因为我需要编写一个脚本来对不同的python文件进行变量值检查。
# filename: zen_basic.py
import importlib
def from_module_import_alias(module_name, var_name, alias):
""" equal to from module import a as b """
agent = importlib.import_module(module_name)
globals()[alias] = vars(agent)[var_name]
奇怪的是,如果我启动一个Python交互式shell,我就无法使用此函数导入内容。但是通过在函数之外使用它的内容,它可以工作。
>>> from zen_basic import *
>>> module_name = 'autor'
>>> var_name = 'food'
>>> alias = 'fd'
>>> from_module_import_alias(moduele_name, var_name, alias)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'moduele_name' is not defined
>>> from_module_import_alias(module_name, var_name, alias)
>>> fd
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'fd' is not defined
>>> agent = importlib.import_module(module_name)
>>> globals()[alias] = vars(agent)[var_name]
>>> fd
'cake'
>>>
我之后又做了3次实验:
python -i test.py
import zen_basic
from_module_import_alias
函数,失败。 python -i zen_basic.py
from_module_import_alias
函数,成功。import zen_basic
代码并将from_module_import_alias function
调用至test.py
python -i test.py
,成功在Python交互式shell中直接使用from_module_import_alias
函数失败的原因是什么?
答案 0 :(得分:5)
您正在更新错误的全局变量。您正在更新zen_basic
模块的全局变量,而不是__main__
模块(脚本的命名空间或交互式解释器)。 globals()
函数总是返回定义代码的模块的全局变量,而不是调用函数的模块。
你必须检索调用帧的全局变量。请注意,很少修改调用框架的全局变量,但如果必须,则可以使用sys._getframe()
function检索调用框架:
import sys
def from_module_import_alias(module_name, var_name, alias):
""" equal to from module import a as b """
agent = importlib.import_module(module_name)
calling_globals = sys._getframe(1).f_globals
calling_globals[alias] = vars(agent)[var_name]
在您的实验中,python -i zen_basic.py
运行zen_basic
作为主脚本条目,因此globals()
引用__main__
模块。