我在多种环境中拥有相当广泛的编码背景,但是,我对 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/