python - 寻求有关用于从外部 '.py' 文件动态导入函数的代码的建议

标签 python dynamic import eval

我在多种环境中拥有相当广泛的编码背景,但是,我对 Python 还很陌生。我以为我已经找到了一种从外部“.py”文件动态导入函数的方法,但不确定这是否是最好的方法。我发现使用 importlib.import_module() 时出现问题和importlib.__import__基于我的目标。还有其他方法可以完成我在这里所做的事情吗?实际上,我希望获得与使用 from x import y 时得到的结果相同的结果其中 x 和 y 是变量。我以为我可以使用eval('from '+x+' import '+y)但这会引发语法错误。

我希望通过设计一个以文件为键的字典(即,名为“file1.py”的文件将创建“file1”的键)和所需函数的列表作为与它的相对键。这可以很容易地从字面上构建,或者通过读取文件名的路径,然后使用 dir() 函数获取每个单独文件中的函数列表(以及许多其他方式)。接下来,我希望简单地使用嵌套for循环遍历字典键及其关联的键值列表并使用 eval('from '+key+' import '+currentListItem) 。不幸的是,这会在执行生成的“from...import...”语句时引发语法错误。请参阅下面的示例代码。我的 importlib (和 getattr)问题是我无法维护此方法提供的“抽象”,因为我必须定义一个“句柄”才能使用 importlib (即 handle = getattr(...)handle = importlib.import_module(key) 意味着我基本上必须为要导入的给定模块硬编码“句柄名称”,因此也可以硬编码“from file_name import function”语句)。

# simplistic example of what I was thinking....
# FILE file.py contains the code...
def asub(p1, p2 = None, p3 = None):
    print(p1, p2 if p2 else 'p2 defaulted', p3 if p3 else 'p3 defaulted')
    return

# FILE b.py contains the code...

#!/usr/local/bin/python3
subs = {'file':['asub']}
for key in subs:
    for subrt in subs[key]:
        print("==>", key, subrt)
        eval('from '+key+' import '+subrt)

# on execution of b.py (i.e., ```python3 b.py``` I get the following...

Traceback (most recent call last):
  File "b.py", line 9, in <module>
    eval('from '+key+' import '+subrt)
  File "<string>", line 1
    from file import asub
       ^
SyntaxError: invalid syntax

注意:我知道这对于导入模块/函数来说可能不是最好的事情,因为它往往会“隐藏”导入函数的文档和使用所需的信息。

但是,我确信在某些情况下这可能有用,或者类似的方法在导入以外的情况下可能有用。

正如我所说,我是 Python 新手,因此,我正在寻找(畏缩的)“Pythonic”意义上的反馈/指导。

另一件事:我知道 eval() 可以打开代码插入的大门,但对于上述特定用途,并且考虑到包含函数的文件被很好地锁定,我认为它应该很安全(?) ...

预先感谢您的任何反馈

最佳答案

试试这个:

from importlib.machinery import SourceFileLoader

subs = {'file':['asub']}

for key in subs:
    # import module by file path
    # since path is relative, it will import against working directory
    mod = SourceFileLoader("", "%s.py" % key).load_module()

    for subrt in subs[key]:
        print("==>", key, subrt)

        # retrieve object from module by name subrt
        obj = getattr(mod, subrt)

        # this should call file.asub and it does
        obj('1', '2')

        # this add local variable with the same name
        locals()[subrt] = obj

# so now we can call asub as if it were done
# from file import asub
asub('3', '4')

此代码打印:

==> file asub
1 2 p3 defaulted
3 4 p3 defaulted

这适用于我的 python3,并且至少需要 python 3.3。这是建立在问题 How to import a module given the full path? 之上的。 locals()[subrt] = obj 将导入的对象放入局部变量目录中,这允许调用它,就像 from file import asub 完成一样。如果我理解正确的话,这就是你想要实现的目标?

关于python - 寻求有关用于从外部 '.py' 文件动态导入函数的代码的建议,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56671433/

相关文章:

c# - 在 C# 中将对象视为属性字典

python - 使用 Jupyter Notebook 安装 wordcloud

javascript - Webpack 解析导入路径的目录(goCardless 作为样板)

python - 使用 nltk 访问 python 中的同义词时出错?

python - 阅读 Python 实现

python - 将 Python 包上传到 PyPI

python-3.x - 属性错误: type object 'numpy.ndarray' has no attribute '__array_function__' on import numpy 1. 15.4

python : How to use if elif for rows in a dataframe

c# - 获取 Func<T> 变量的参数

php - 在 PHP 中从具有动态类名的类中获取静态属性