问题描述
我记下了导入的标准方法。
import module as m
我还注意到,可以按如下方式在函数中导入模块。
def someFunction():
import module as m
# do some things
return
我还注意到嵌套函数具有作用域,这样内部函数变量具有仅限于该函数的局部作用域。
鉴于上述情况,我想(安全)导入两个不同的模块,但两者都具有相同的别名,如下所示:在此示例中,这两个模块是 test_params
和 test_params2
,别名(两者通用,但嵌套)是 p
。
import test_params as p
print(p.x)
def some_code():
import test_params2 as p
print(p.x)
return
some_code()
如果 test_params
的 x=100 并且 test_params2
的 x=10,那么预期的结果是:
100
10
我测试时是什么。
我的问题是:以上是可以接受和理解的(pythonic,没有冲突)还是有更好的方法?
解决方法
参考文档:https://docs.python.org/3/reference/import.html
- “import 语句结合了两个操作;它搜索命名模块,然后将该搜索的结果绑定到本地范围内的一个名称。”
- 这意味着您不会通过在函数内部进行额外导入来“污染”您的命名空间,它只会覆盖整个模块。您可以通过引用
test_params
中test_params2
中没有的内容来测试这一点,some_code
内(它不起作用) - 但是,每次调用该函数时都会执行导入。这可能是也可能不是问题(取决于性能)。
- 此外,此方法不够灵活,因为它不允许覆盖(例如,覆盖存在的映射,但保留未被覆盖的映射)
- 这意味着您不会通过在函数内部进行额外导入来“污染”您的命名空间,它只会覆盖整个模块。您可以通过引用
如果您想要一种方法为不同的函数指定不同的模块来源映射,从而允许覆盖(即来自基础模块的默认值),您可以执行以下操作:
import test_params
import test_params2
def module_map(*modules):
result = {}
for module in modules:
new_values = {item:getattr(module,item) for item in dir(module) if not item.startswith("__")}
result.update(new_values)
return result
def some_code():
val_map = module_map(test_params,test_params2)
print("out2:",val_map)
return
print("out:",module_map(test_params))
some_code()
test_params:
y = 8
x = 50
z = 10
test_params2:
y = 200
x = 100
输出:
out: {'x': 50,'y': 8,'z': 10}
out2: {'x': 100,'y': 200,'z': 10}