在运行时加载python代码

Sha*_*baz 17 python runtime python-import

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

var1=value  
var2=value  
predicate_function=func line : <return true or false>  
Run Code Online (Sandbox Code Playgroud)

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

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

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

Clé*_*ent 14

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...
Run Code Online (Sandbox Code Playgroud)

您还可以使用__import__语句的返回值,但您必须完全了解python如何使用命名空间和范围.

  • mmh,nope,在我的例子中,它将返回`myproject`模块而不是'myproject.mymodule`.直接来自doc:_当name变量的形式为package.module时,通常会返回顶级包(直到第一个点的名称),而不是name._命名的模块. (2认同)

for*_*ger 10

您只需要能够动态指定导入,然后动态获取变量.

假设您的配置文件是bar.py,如下所示:

x = 3
y = 4
def f(x): return (x<4)
Run Code Online (Sandbox Code Playgroud)

然后你的代码应该是这样的:

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]
Run Code Online (Sandbox Code Playgroud)

我得到这个输出:

bar f <function f at 0x7f2354eb4cf8>
bar x 3
bar y 4
Run Code Online (Sandbox Code Playgroud)

然后你至少拥有所有的变量和功能.我没有从谓词函数中得到你想要的东西,但也许你现在可以自己得到它.


Mik*_*ham 7

要访问另一个Python模块,请导入它.execfile一对夫妇已经提到过,但这是一个混乱和危险的.execfile弄乱你的命名空间,甚至可能弄乱你正在运行的代码.如果要访问其他Python源文件,请使用该import语句.

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


oef*_*efe 7

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

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

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