我想在运行时加载.py
文件。这个.py
文件基本上是一个配置文件,格式如下:
var1=value
var2=value
predicate_function=func line : <return true or false>
加载此文件后,我希望能够访问var1
,var2
和predicate_function
。对于每一行,我将它传递给谓词函数,如果它返回false,我将忽略它。
在任何情况下,我都不确定如何在运行时加载python文件并访问其变量。
澄清:我可能需要将任意数量的配置文件传递给主程序,直到运行时我才会知道它们的名称。谷歌告诉我应该使用__import__
。我不确定如何正确使用该方法,然后访问导入文件的变量。
答案 0 :(得分:14)
如python official documentation所述,如果您只是想按名称导入模块,可以在使用sys.modules
后在__import__
字典中查找。
假设您的配置位于myproject.mymodule
,您可以这样做:
module_name = 'myproject.mymodule'
import sys
__import__(module_name)
mymodule = sys.modules[module_name]
# Then you can just access your variables and functions
print mymodule.var1
print mymodule.var2
# etc...
您还可以使用__import__
语句的返回值,但必须完全理解how python works with namespaces and scopes。
答案 1 :(得分:10)
您只需要能够动态指定导入,然后动态获取变量。
假设您的配置文件是bar.py,如下所示:
x = 3
y = 4
def f(x): return (x<4)
然后你的代码应该是这样的:
import sys
# somehow modnames should be a list of strings that are the names of config files
#
# you can do this more dynamically depending on what you're doing
modnames = ['bar']
for modname in modnames:
exec('import %s' % modname)
for modname in modnames:
mod = sys.modules[modname]
for k in mod.__dict__:
if k[:2] != '__':
print modname, k, mod.__dict__[k]
我得到了这个输出:
bar f <function f at 0x7f2354eb4cf8>
bar x 3
bar y 4
然后你至少拥有所有的变量和功能。我从谓词函数中得不到你想要的东西,但也许你现在可以自己得到它。
答案 2 :(得分:7)
要访问其他Python模块,您导入。一些人已经提到过execfile
,但它很混乱而且非常危险。 execfile
使您的命名空间变得混乱,甚至可能弄乱您正在运行的代码。如果要访问其他Python源文件,请使用import
语句。
更好的是根本不使用Python文件进行配置,而是使用内置模块ConfigParser
或像JSON这样的序列化格式。这样,您的配置文件不允许执行任意(可能是恶意的)代码,不需要人们知道Python来配置您的程序,并且可以以编程方式轻松地进行更改。
答案 3 :(得分:7)
答案 4 :(得分:2)
在Python 2.*
中,execfile有效(我建议传递一个特定字典并从那里访问变量 - 正如文档中的说明所说,execfile
不能影响调用函数的locals()
字典)。
在Python 3.*
中,execfile已被删除,反之亦然:
with open('thefile.py') as f:
exec(f.read(), somedict)
答案 5 :(得分:2)
我有点迟到了,但我想提出一个替代答案。
如果要在不影响全局模块名称空间的情况下导入代码,可以创建一个匿名模块(使用types.ModuleType
)并在其中加载任意代码(使用compile
和exec
) 。例如,像这样:
import types
filename = "/path/to/your/file.py"
with open(filename) as fp:
code = compile(fp.read(), filename, "exec")
config_module = types.ModuleType("<config>")
exec code in config_module.__dict__
然后,您可以将变量视为config_module.var1
,&amp; c。
答案 6 :(得分:1)
如果你想要一个只在程序没有运行时由用户编辑的配置文件,只需将它作为普通的python文件导入
即
main.py:
import config
print config.var1
config.py:
var="var12"
var2 = 100.5
答案 7 :(得分:0)
答案 8 :(得分:0)
由于Python版本尚未明确提及,因此值得指出的是, imp 模块在较新的Python版本中已被弃用,而不是importlib模块。 Example here.