文件

时间:2017-11-29 17:44:17

标签: python

我有多个文件,其结构类似于文件example.py

    def initialize(context):
        pass


    def daj_omacku_teplu(context, data):
        pass


    def hmataj_pomaly(context, data):
        pass


    def chvatni_paku(context, data):
        pass


    def mikaj_laktom(context, data):
        pass

我需要能够从" example.py"动态导入方法。在另一个python文件中,如:

    for fn in os.listdir('.'):
       if os.path.isfile(fn):
           from fn import mikaj_laktom
           mikaj_laktom(example_context, sample_data)

由于多种原因,我无法更改example.py的结构,因此我需要建立一种机制来加载方法并对其进行评估。我尝试使用importlib,但它只能导入一个类,而不能只导入定义方法的文件。 谢谢你的帮助。

2 个答案:

答案 0 :(得分:1)

Python不支持使用路径导入,因此您需要将这些文件作为模块访问,请参阅(sys.path)。假设您的源位于与主脚本相同的文件夹中,我将使用以下(或类似):

import sys

def load_module(module):

    # module_path = "mypackage.%s" % module
    module_path = module

    if module_path in sys.modules:
        return sys.modules[module_path]

    return __import__(module_path, fromlist=[module])

# Main script here... Could be your for loop or anything else
# `m` is a reference to the imported module that contains the functions
m = load_module("example")
m.mikaj_laktom(None, [])

源文件也可以是另一个包的一部分,在这种情况下,您需要__init__.py.py文件位于同一文件夹中(请参阅packages)并导入“mypackage.module”表示法。 (请注意,顶级文件夹应位于您的路径中,在上面的示例中,这是包含“mypackage”的文件夹)

答案 1 :(得分:0)

您与importlib走在了正确的轨道上。它可以用于按名称加载模块,但是我不认为你可以用这种方式将它们加载到全局命名空间中(如from module import function中所示)。因此,您需要将它们作为模块对象加载并调用所需的方法:

import glob, importlib, os, pathlib, sys

# The directory containing your modules needs to be on the search path.
MODULE_DIR = '/path/to/modules'
sys.path.append(MODULE_DIR)

# Get the stem names (file name, without directory and '.py') of any 
# python files in your directory, load each module by name and run
# the required function.
py_files = glob.glob(os.path.join(MODULE_DIR, '*.py'))

for py_file in py_files:
    module_name = pathlib.Path(py_file).stem
    module = importlib.import_module(module_name)
    module.mikaj_laktom()

另外,请谨慎使用'.'作为MODULE_DIR,因为这可能会尝试加载当前的python文件,这可能会导致一些意外行为。

编辑:如果使用Python2,标准库中不会有pathlib,所以请使用

module_name = os.path.splitext(os.path.split(py_file)[1])[0]

获得相当于Path.stem