在运行时加载Python代码

发布于 2024-08-20 23:43:29 字数 488 浏览 2 评论 0 原文

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

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

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

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

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

I would like to load a .py file at runtime. This .py file is basically a config file with the following format:

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

Once this file is loaded, I would like to be able to access var1, var2 and predicate_function. For each line, I'll pass it to the predicate function, and if it returns false, I'll ignore it.

In any case, I'm not sure how to load a python file at runtime and access its variables.

Clarification: there may be any number of these config files that I need to pass to the main program and I won't know their names until runtime. Google tells me I should use __import__. I'm not sure how to correctly use that method and then access the variables of the imported file.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

琉璃梦幻 2024-08-27 23:43:29

正如python官方文档中所写,如果您只想通过以下方式导入模块名称,您可以使用__import__后在sys.modules字典中查找。

假设您的配置位于 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__ 语句的返回值,但您必须完全理解 Python 如何使用命名空间和作用域

As written in the python official documentation, if you just want to import a module by name, you can look it up in the sys.modules dictionary after using __import__.

Supposing your configuration is in myproject.mymodule, you would do like that :

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...

You can also use the return value of __import__ statement but you will have to understand fully how python works with namespaces and scopes.

音栖息无 2024-08-27 23:43:29

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

假设您的配置文件是 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

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

You just need to be able to dynamically specify the imports and then dynamically get at the variables.

Let's say your config file is bar.py and looks like this:

x = 3
y = 4
def f(x): return (x<4)

Then your code should look like this:

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]

I get this output:

bar f <function f at 0x7f2354eb4cf8>
bar x 3
bar y 4

Then you at least have all the variables and functions. I didn't quite get what you wanted from the predicate functions, but maybe you can get that on your own now.

橙味迷妹 2024-08-27 23:43:29

要访问另一个 Python 模块,您需要导入它。 execfile 已经被几个人提到过,但它很混乱且危险。 execfile 会扰乱您的命名空间,甚至可能会扰乱您正在运行的代码。当您想要访问另一个 Python 源文件时,请使用 import 语句。

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

To access another Python module, you import it. execfile has been mentioned by a couple people, but it is messy and dangerous. execfile clutters your namespace, possibly even messing up the code you are running. When you want to access another Python source file, use the import statement.

Even better would be not to use a Python file for configuration at all, but rather to use the builtin module ConfigParser or a serialization format like JSON. This way your configuration files don't allow execution of arbitrary (possibly malicious) code, doesn't require people to know Python to configure your program, and can easily be altered programatically.

梦忆晨望 2024-08-27 23:43:29

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

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

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

If the imported module is on the regular search path, you can use __import__.

If you need to load the module from an arbitrary path in the filesystem, use imp.load_module.

Be sure to consider the security implications of loading arbitrary user-specified code.

酒几许 2024-08-27 23:43:29

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

在 Python 3.* 中,execfile 已被删除,因此改为:

with open('thefile.py') as f:
  exec(f.read(), somedict)

In Python 2.*, execfile works (I recommend passing a specific dictionary and accessing the variables from there -- as the note in the docs says, execfile can't affect the calling function's locals() dictionary).

In Python 3.*, execfile has been removed, so do, instead:

with open('thefile.py') as f:
  exec(f.read(), somedict)
情丝乱 2024-08-27 23:43:29

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

Since the Python version hasn't been clearly mentioned, it is worth pointing out that the imp module has been deprecated in newer Python versions in favor of the importlib module. Example here.

自我难过 2024-08-27 23:43:29

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

如果要导入代码而不影响全局模块命名空间,可以创建一个匿名模块(使用 types.ModuleType)并在其中加载任意代码(使用 compile 和 <代码>执行)。例如,如下所示:

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 等变量。

I'm kinda late to the party, but I want to present an alternative answer nonetheless.

If you want to import code without affecting the global module namespace, you can create an anonymous module (using types.ModuleType) and load arbitrary code in it (using compile and exec). For instance, like this:

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__

You can then access the variables as config_module.var1, &c.

请恋爱 2024-08-27 23:43:29

如果你想要一个仅在程序未运行时由用户编辑的配置文件,只需将其作为普通的 python 文件导入

即可。

main.py:

import config
print config.var1

配置.py:

var="var12"
var2 = 100.5

If you want to have a configuration file that will only be edited by the user when the program isn't running, just import it as a normal python file

ie.

main.py:

import config
print config.var1

config.py:

var="var12"
var2 = 100.5
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文