Python,导入Python代码的字符串作为模块

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中尝试元编程,这似乎是我正在做的一个很好的解决方案.

Jer*_*own 14

这是使用imp模块动态创建模块对象的示例

  • 请将您的外部链接中的基本答案信息复制到答案正文中.因此,如果远程站点移动内容或停止运行,解决方案不会丢失. (7认同)

小智 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)


Rem*_*emi 5

以下是如何将字符串作为模块导入:

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)


kir*_*sos 5

不幸的是,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)

或者您可以使用PyExtRuntimeModule.from_string

from pyext import RuntimeModule

mod = RuntimeModule.from_string('a = 1')
print(mod.a) # 1
Run Code Online (Sandbox Code Playgroud)