18

我想.py在运行时加载一个文件。这个.py文件基本上是一个配置文件,格式如下:

var1=value  
var2=value  
predicate_function=func line : <return true or false>  

加载此文件后,我希望能够访问var1,var2predicate_function. 对于每一行,我会将它传递给谓词函数,如果它返回 false,我将忽略它。

无论如何,我不确定如何在运行时加载 python 文件并访问它的变量。

澄清:我可能需要将任意数量的这些配置文件传递给主程序,直到运行时我才会知道它们的名称。谷歌告诉我应该使用__import__. 我不确定如何正确使用该方法,然后访问导入文件的变量。

4

9 回答 9

16

如python官方文档中所写,如果只想按名称导入模块,可以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__statement 的返回值,但您必须完全了解 python 如何使用 namespaces 和 scopes

于 2010-02-14T09:47:18.307 回答
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

那么你至少拥有所有的变量和函数。我没有完全从谓词函数中得到你想要的,但也许你现在可以自己得到它。

于 2010-02-14T09:24:21.910 回答
7

要访问另一个 Python 模块,请导入它execfile有几个人提到过,但它是混乱和危险的。execfile混乱你的命名空间,甚至可能弄乱你正在运行的代码。当您想访问另一个 Python 源文件时,请使用该import语句。

更好的是根本不使用 Python 文件进行配置,而是使用内置模块ConfigParser或 JSON 等序列化格式。这样,您的配置文件就不允许执行任意(可能是恶意的)代码,不需要人们知道 Python 来配置您的程序,并且可以很容易地以编程方式进行更改。

于 2010-02-14T00:00:42.863 回答
7

如果导入的模块在常规搜索路径上,您可以使用__import__.

如果您需要从文件系统中的任意路径加载模块,请使用imp.load_module.

请务必考虑加载任意用户指定代码的安全隐患。

于 2010-02-14T09:18:46.813 回答
2

在 Python2.*中,execfile有效(我建议传递一个特定的字典并从那里访问变量——正如文档中的注释所说,execfile不能影响调用函数的locals()字典)。

在 Python3.*中, execfile 已被删除,所以这样做:

with open('thefile.py') as f:
  exec(f.read(), somedict)
于 2010-02-13T23:05:31.890 回答
2

我参加聚会有点晚了,但我还是想提出一个替代答案。

如果要在不影响全局模块命名空间的情况下导入代码,可以创建一个匿名模块(使用types.ModuleType)并在其中加载任意代码(使用compileexec)。例如,像这样:

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, &c。

于 2014-04-08T21:37:56.273 回答
1

如果你想拥有一个只有在程序不运行时才由用户编辑的配置文件,只需将其作为普通 python 文件导入即可

IE。

主要.py:

import config
print config.var1

配置文件:

var="var12"
var2 = 100.5
于 2010-02-13T23:02:44.147 回答
1

由于尚未明确提及 Python 版本,因此值得指出的是,在较新的 Python 版本中已弃用imp模块,取而代之的是importlib模块。这里的例子。

于 2016-10-02T17:52:30.413 回答
0

尝试 imp 模块:http ://docs.python.org/library/imp.html

于 2011-02-04T23:29:56.007 回答