我有多个文件,其结构类似于文件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
,但它只能导入一个类,而不能只导入定义方法的文件。
谢谢你的帮助。
答案 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
。