
一段源码
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 都可以,具体就看你想要的作用范围啦。哈哈哈哈哈 |