从python文件列表动态加载对象

时间:2018-05-04 19:25:09

标签: python

我想知道我是否在文件夹中有一些python脚本,它们具有方法名称等常用功能,但可以动态导入不同的功能。这些python脚本将在一个文件夹中,但我不知道他们将有多少。我想在文件夹中查看脚本,获取脚本列表并为每个脚本创建对象。

2 个答案:

答案 0 :(得分:2)

您所描述的是通常称为插件系统的内容。

对于Python 3.4及更高版本,有a standard recipe for importing a source file

唯一要做的事情是:(a)枚举指定目录中的所有源文件,以及(b)在加载完每个模块后调用一些工厂/注册/任何函数。

所以:

set(_lua_library_names
    lua${LUA_VERSION_MAJOR}${LUA_VERSION_MINOR}
    lua${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}
    lua-${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}
    lua.${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}
)

def load_module(path): name = os.path.split(path)[-1] spec = importlib.util.spec_from_file_location(name, path) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) return module plugins = [] for fname in os.listdir(PLUGIN_DIR): if not fname.startswith('.') and fname.endswith('.py'): try: module = load_module(os.path.join(PLUGIN_DIR, fname) plugins.append(module.plugin_factory()) 只是一个"创建一个对象的函数或类。对于每个模块。你可以随意调用它。通常,每个插件都提供一个类,它是您定义的某种类型的子类(或类型为duck-types),或者提供一个返回您定义的某个类的实例的函数。但在非常简单的情况下,您可以将模块本身用作插件对象。在这种情况下,当然,最后一行只是plugin_factory

显然,如果您想通过名称访问插件而不是仅仅迭代它们(并且它们没有plugins.append(module)属性),您将要将它们存储在dict而不是列表。

当然,您可以将它们添加到name,就像文档中的食谱一样,但通常您不需要它。

答案 1 :(得分:1)

假设我们在当前目录中有三个文件。

a.py:

def f():
    pass

b.py:

def g():
    pass

c.py:

def h():
    pass

以下main.py脚本扫描当前目录中的python文件,并根据需要导入它们:

import os

modules = {}
for f in os.listdir('.'):
    if os.path.isfile(f) and f.endswith('.py') and f != 'main.py':
        modname = f[:-3] # remove '.py' extension
        modules[modname] = __import__(modname)

# now the various functions are available via:
modules['a'].f()
modules['b'].g()
modules['c'].h()

在Python> = 3.4中,您可以使用importlib模块,并避免__import__,在python docs中不鼓励使用它:

import os
import importlib

modules = {}
for f in os.listdir('.'):
    if os.path.isfile(f) and f.endswith('.py') and f != 'main.py':
        modname = f[:-3] # remove '.py' extension
        spec = importlib.util.spec_from_file_location(modname, f)
        modules[modname] = importlib.util.module_from_spec(spec)
        spec.loader.exec_module(modules[modname])

modules['a'].f()
modules['b'].g()
modules['c'].h()