动态包含和调用多个Python模块的函数

-1 投票
1 回答
32 浏览
提问于 2025-04-12 23:14

介绍

你好!我正在做一个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)

撰写回答