动态包含和调用多个Python模块的函数
介绍
你好!我正在做一个Python项目,想从一个文件夹里加载任意数量的.py文件,然后在这些文件里,如果有某个函数存在,就调用它。我可以遍历文件夹里的所有.py文件并把它们引入,但当我尝试对这些模块进行操作时,就出现了问题。
这个脚本应该:
- 列出“modules”文件夹里所有的.py文件
- 把这些文件导入到一个列表、字典、数组或对象中
- 如果找到了特定的函数,就有条件地调用它
我们不知道文件夹里有多少个.py文件,也不知道哪些文件里有正确的函数。
安装
- 操作系统:微软Windows 11
- Python版本:3.10.4
文件夹结构
- /main.py
- /modules/one.py
- /modules/two.py
- /modules/three.py
- /modules/imposter.txt
项目文件
main.py
# Import the ability to list files and directories.
import glob
import os.path
# Load a list of py-files from the modules-directory.
files = map(os.path.basename, glob.glob("modules/*.py"))
# Initialize an empty dictionary of imported modules with a dynamic length.
modules = {}
# Iterate through all the files...
for file in files:
print("Importing " + file)
modules[file] = __import__("modules", globals(), locals(), [file], 0)
modules/one.py
print("one.py says hi!")
sayBye = "foo"
modules/two.py
print("two.py says hello!")
def sayBye():
print("two.py says bye!")
modules/three.py
print("three.py says hello!")
输出
到目前为止,项目的输出是:
>python main.py
Importing one.py
one.py says hello!
Importing two.py
two.py says hello!
Importing three.py
three.py says hello!
Press any key to continue . . .
好的,进展顺利。文件已经加载了。现在,我想实现一个功能,检查这些文件里是否有一个叫“sayBye”的函数,如果有,就调用它。
问题
main.py
在文件的末尾添加了:
print("--")
for module in modules:
if "sayBye" in dir(module):
if callable(getattr(module, "sayBye")):
module.sayBye()
else:
print("sayBye is not a function.")
else:
print("sayBye could not be found.")
预期结果
>python main.py
Importing one.py
one.py says hello!
Importing two.py
two.py says hello!
Importing three.py
three.py says hello!
--
sayBye is not a function.
two.py says bye!
sayBye could not be found.
Press any key to containue . . .
实际结果
>python main.py
Importing one.py
one.py says hello!
Importing two.py
two.py says hello!
Importing three.py
three.py says hello!
--
sayBye could not be found.
sayBye could not be found.
sayBye could not be found.
Press any key to containue . . .
看起来module
要么无效,要么验证函数的功能有问题。期待反馈。谢谢!
1 个回答
-1
modules
是一个字典。字典里的“键”是文件名,而“值”是模块。当你说
for module in modules:
时,你是在遍历这些键,也就是文件名。你其实想要的是:
for module in modules.values():
后续问题
另一个问题是,你的导入模块实际上是在做
import modules
结果是,所有的模块都用同一个名字引入。这样你就会得到三个指向同一个模块对象的引用。你需要使用正确的名字,比如 modules/one
等等:
# Iterate through all the files...
for file in files:
base = os.path.splitext(file)[0]
print("Importing",file,"as",base)
modules[file] = __import__("modules."+base, globals(), locals(), [file], 0)