Mik*_*ike 16 python metaprogramming
在Python中,你可以做这样的事情来导入使用字符串文件名的模块,并指定其命名空间的本地命名空间的变量.
x = __import__(str)
Run Code Online (Sandbox Code Playgroud)
我想知道,如果有,将采取采取的,而不是用Python代码文件的路径Python代码串,并返回其命名空间为变量的相关功能.
例如,
str = "a = 5";
x = importstr(str)
print x.a
#output is 5
Run Code Online (Sandbox Code Playgroud)
我意识到我可以将字符串写入文件,然后使用__import__它,但我想跳过中间文件,如果可能的话.
这样做的原因是我在python中尝试元编程,这似乎是我正在做的一个很好的解决方案.
小智 6
根据有关module_from_spec()的 Python 文档,不推荐 types.ModuleType :
importlib.util.module_from_spec(规范)
...
此函数优于使用 types.ModuleType 创建新模块,因为 spec 用于在模块上设置尽可能多的导入控制属性。
这是我想出的从源代码加载模块的方法。
import importlib.util
spec = importlib.util.spec_from_loader('helper', loader=None)
helper = importlib.util.module_from_spec(spec)
exec('a = 5', helper.__dict__)
print(type(helper)) # prints "<class 'module'>"
helper.a # prints "5"
Run Code Online (Sandbox Code Playgroud)
以下是如何将字符串作为模块导入:
import sys,imp
my_code = 'a = 5'
mymodule = imp.new_module('mymodule')
exec my_code in mymodule.__dict__
Run Code Online (Sandbox Code Playgroud)
所以你现在可以访问模块属性(和函数,类等):
mymodule.a
>>> 5
Run Code Online (Sandbox Code Playgroud)
要忽略下次导入的任何尝试,请将模块添加到sys:
sys.modules['mymodule'] = mymodule
Run Code Online (Sandbox Code Playgroud)
不幸的是,imp最近不推荐使用该模块(我不知道为什么)。
相反,您应该这样做:
from types import ModuleType
import sys
mod = ModuleType('my_module', 'doc string here')
exec('a = 1', mod.__dict__)
print(mod.a) # prints 1
# add to sys.modules
sys.modules['my_module'] = mod
Run Code Online (Sandbox Code Playgroud)
或者您可以使用PyExt的RuntimeModule.from_string:
from pyext import RuntimeModule
mod = RuntimeModule.from_string('a = 1')
print(mod.a) # 1
Run Code Online (Sandbox Code Playgroud)