一段源码
import importlib
packages = ['pathlib', 'sys']
modules = ['Path', 'path']
for idx, package in enumerate(packages):
tmp = importlib.import_module(package)
importlib.reload(tmp)
execline = modules[idx] + ' = getattr(tmp, "' + modules[idx] + '")'
print(execline)
exec(execline)
# importlib.import_module('pathlib'); importlib.reload(pathlib); Path = getattr(pathlib, 'Path')
# import pathlib; importlib.reload(pathlib); from pathlib import Path
请问各路高人,有什么办法能替代上面的 exec?
稍微解释一下。exec 那句的功能是要动态载入数个我自己的函数…… 不过我用了系统的包做例子。非动态下 2 行 # 行其中的任一行都可以实现 exec行的功能。
之所以不想用 exec 一是因为 pylint 出警告信息,二是因为 execline 这种写法太丑也容易出错。
1
264768502 2017-07-09 21:27:42 +08:00 via Android
用 locals?
|
2
yucongo OP @264768502 大侠可不可以说仔细一点,感谢。
eval(...) 一般都可以用 dict 和 getattrib 实现,我在找实现 exec(...) 办法。网上好像说 eval 和 exec 都可以用别的办法代替。 |
3
ZRS 2017-07-09 21:36:25 +08:00
locals()["func_name"]
|
4
josephshen 2017-07-09 21:38:24 +08:00 via iPhone
参见
importlib.util.module_from_spec 和 importlib.util.spec_from_file_location |
6
yucongo OP @josephshen 感谢,我 google 一下
|
7
yucongo OP @ZRS locals()["func_name"] 只是拿到 module 的名字,其实是源码里的 tmp, 可我要的是 module 的 方法(给定'pathlib' 和 'Path', 实现 from pathlib import Path)。
@josephshen importlib.util.module_from_spec 和 importlib.util.spec_from_file_location 貌似都搜索 module 的名字。可我要的是 module 的 方法(例如,给定'pathlib' 和 'Path', 实现 from pathlib import Path)。 |
8
yucongo OP 请各路高人继续支招,先感谢。
我再简化一下问题,考虑下面的源码 module_name = 'pathlib' tmp = importlib.import_module(module_name) # 等效 import pathlib; tmp = pathlib importlib.reload(tmp) # 等效 importlib.reload(pathlib) ? ?? # 如何不用 exec 实现 from pathlib import Path? # 用 exec 的话可以凑一个 execline = "Path = getattr(tmp, 'Path')" 送给 exec(execline) # 等效运行了 Path = getattrib(pathlib, 'Pah') , 等效于 from pathlib import Path |
9
lrxiao 2017-07-09 23:38:06 +08:00
tmp.__dict__['Path']不行吗
|
10
lrxiao 2017-07-09 23:46:03 +08:00
等下 你要限定这个函数叫 Path。。。那我不知道了
|
11
mckelvin 2017-07-09 23:52:55 +08:00
|
12
josephshen 2017-07-10 00:06:40 +08:00 via iPhone
再直接 moudle.__dict__[fun_name]就可以了啊,我有种感觉你应该没什么 python 的经验……,那些函数只是普通变量,你获得函数变量后想怎么命名就怎么命名啊
|
13
yucongo OP 感谢楼上各位。
我想我知道怎么做了。8 楼问题的答案是: globals()['Path'] = getattrib(tmp, 'Path') 0 楼的 exec 行可以用下面的码代替: globals()[modules[idx]] = getattrib(tmp, modules[idx]) |
14
imn1 2017-07-10 08:14:12 +08:00
google "动态导入模块"
|
15
ToBeHacker 2017-07-10 10:16:15 +08:00
|
16
ledzep2 2017-07-10 16:21:10 +08:00
感觉问题有点误导. 核心是如何替代 exec 里的 assign. 和 import module 啥的关系都不大.
|
17
yucongo OP @ledzep2 是啊,有些大侠不审题就给答案 ;), 而且提的问题里已经用了 importlib。不过还是感谢各位……
|
18
josephshen 2017-07-10 19:51:27 +08:00 via iPhone
哈哈哈哈哈,原来你的核心问题就是如何动态创建一个名为 xxx 的变量。那 locals 和 globals 都可以,具体就看你想要的作用范围啦。哈哈哈哈哈
|