Mad*_*ist 2 python-import python-3.x
为了说明我正在尝试做什么,假设我有一个testmod位于./testmod.py. 这个模块的全部内容是
x = test
Run Code Online (Sandbox Code Playgroud)
我希望能够使用任何可用的工具importlib或任何其他内置库成功地将此模块导入 Python 。
显然import testmod从当前目录做一个简单的语句会导致错误:NameError: name 'test' is not defined.
我想,也许无论是传球globals还是locals要__import__正确地将修改剧本正在运行的内部环境,但事实并非如此:
>>> testmod = __import__('testmod', globals={'test': 'globals'}, locals={'test': 'locals'})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/jfoxrabi/testmod.py", line 1, in <module>
x = test
NameError: name 'test' is not defined
Run Code Online (Sandbox Code Playgroud)
我以不同的方式设置了 test 的值,这样我就可以看到testmod.x如果这行得通,我可以看到哪个 dict来自。
由于这些似乎都不起作用,我被卡住了。甚至有可能完成我想要做的事情吗?我猜是的,因为这是 Python,而不是 Sparta。
我在 Anaconda 上使用 Python 3.5。我非常不想使用外部库。
更新:为什么
我将一个模块作为配置文件导入到我的程序中。我不使用 JSON 或 INI 的原因是我希望 Python 解释器的完整范围可用于从表达式计算配置中的值。我想在程序中预先计算某些值以进行这些计算。
虽然我知道这和调用一样糟糕eval(我在我的程序中也是这样做的),但我暂时不关心安全方面。但是,如果这确实是 XY 的情况,我非常愿意接受更好的解决方案。
我想出了一个基于这个答案和importlib docs的解决方案。基本上,我可以通过使用正确的调用顺序在加载模块对象之前访问它importlib:
from importlib.util import spec_from_file_location, module_from_spec
from os.path import splitext, basename
def loadConfig(fileName):
test = 'This is a test'
name = splitext(basename(fileName))[0]
spec = spec_from_file_location(name, fileName)
config = module_from_spec(spec)
config.test = test
spec.loader.exec_module(config)
return config
testmod = loadConfig('./testmod.py')
Run Code Online (Sandbox Code Playgroud)
这比修改 好一点builtins,这可能会在程序的其他部分产生意想不到的后果,并且还可能限制我可以传递给模块的名称。
我决定将所有配置项放入一个在加载时可访问的字段中,我将其命名为config. 这使我可以在以下内容中执行以下操作testmod:
if 'test' in config:
x = config['test']
Run Code Online (Sandbox Code Playgroud)
加载器现在看起来像这样:
from importlib.util import spec_from_file_location, module_from_spec
from os.path import splitext, basename
def loadConfig(fileName, **kwargs):
name = splitext(basename(fileName))[0]
spec = spec_from_file_location(name, fileName)
config = module_from_spec(spec)
config.config = kwargs
spec.loader.exec_module(config)
return config
testmod = loadConfig('./testmod.py', test='This is a test')
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
677 次 |
| 最近记录: |