Python 为文件夹中的每个脚本调用函数

Python 为文件夹中的每个脚本调用函数,python,module,Python,Module,是否有一种方法(仅使用python,即:不使用bash脚本或其他语言代码)来调用文件夹中每个脚本中的特定函数,而无需显式导入所有脚本 例如,假设这是我的结构: main.py modules/ module1.py module2.py module3.py module4.py 每个moduleX.py都有以下代码: import os def generic_function(caller): print('{} was called by {}'

是否有一种方法(仅使用python,即:不使用bash脚本或其他语言代码)来调用文件夹中每个脚本中的特定函数,而无需显式导入所有脚本

例如,假设这是我的结构:

main.py
modules/
    module1.py
    module2.py
    module3.py
    module4.py
每个
moduleX.py
都有以下代码:

import os

def generic_function(caller):
    print('{} was called by {}'.format(os.path.basename(__file__), caller))

def internal_function():
    print('ERROR: Someone called an internal function')
import modules
import os

for module in modules.some_magic_function():
    module.generic_function(os.path.basename(__file__))
main.py
有以下代码:

import os

def generic_function(caller):
    print('{} was called by {}'.format(os.path.basename(__file__), caller))

def internal_function():
    print('ERROR: Someone called an internal function')
import modules
import os

for module in modules.some_magic_function():
    module.generic_function(os.path.basename(__file__))
因此,如果我运行
main.py
,我将得到以下输出:

module1.py was called by main.py
module2.py was called by main.py
module3.py was called by main.py
module4.py was called by main.py
*请注意,不应调用
内部函数()
(与此不同)。此外,我不想显式地声明每个模块文件,即使是在
\uuuu init\uuuuuu.py

顺便说一句,我不介意使用类来实现这一点。事实上,它可能会更好。

您可以使用或来实现这一点。所以它大致是这样的(对于
exec
):

这里的假设是您根本不打算导入模块


请注意,以这种不受限制的方式使用
exec
与以下内容有关。您可以。

虽然Sophos的方法对于隐式导入模块来说已经足够快了,但您可能会遇到与控制每个模块或复杂调用相关的问题(比如每个调用都有条件)。因此,我分别采用了另一种方法:

首先,我创建了一个声明了函数(现在是方法)的类。这样,我可以避免检查该方法是否存在,因为如果我没有声明它,我可以使用默认方法:

# main.py
class BaseModule:
    def __init__(self):
        # Any code
    
    def generic_function(self, caller):
        # This could be a Print (or default return value) or an Exception
        raise Exception('generic_function wasn\'t overridden or it was used with super')
    
然后我创建了另一个扩展BaseModule的类。遗憾的是,在不知道子类的名称的情况下,我无法找到检查内在性的好方法,因此我对每个模块使用了相同的名称:

# modules/moduleX.py
from main import BaseModule

class GenericModule(BaseModule):
    def __init__(self):
        BaseModule.__init__(self)
        # Any code
    
    def generic_function(self, caller):
        print('{} was called by {}'.format(os.path.basename(__file__), caller))
最后,在我的
main.py
中,我使用了
importlib
来动态导入模块并为每个模块保存一个实例,以便以后使用它们(为了简单起见,我没有将它们保存在下面的代码中,但使用列表并将每个实例添加到其中很容易):

参考资料:

[1]

[2]


[3]

您能否澄清“无需全部导入”的含义?您的意思是不显式导入它们,例如
导入模块1
,还是完全不导入它们,例如只隐式导入那些定义了
通用功能的模块?@MisterMiyagi通过“不需要导入所有模块”我的意思是不需要执行
导入模块1、模块2、模块3、模块4、,module5
(即显式导入),但我至少需要对模块进行某种控制(例如,如果
generic_function()
为某个模块返回True,然后为同一个模块调用另一个函数),很抱歉我不清楚如何导入模块
eval
可能是一个不错的选择,因为有些函数会返回一些值(主要是布尔值),但我担心读取和调用每个模块可能会产生内存泄漏或类似的问题,因为我原来的main.py会无限期运行(为了简单起见,我没有告诉大家)。有没有一种方法可以让类似于您建议的代码的东西,但每个模块只导入一次,然后从列表或类似的东西中引用它们?这是一个毫无根据的担忧-每个循环只导入一次模块,并且在执行后收集垃圾。这种方法不必担心内存泄漏。很高兴知道(我有预感,但我不确定)。我还有一个问题:为同一个模块调用两个函数如何,但取决于第一个函数的值。例如:如果
generic_function()
返回
true
,则调用
internal_function()
(对于同一模块)并中断循环。否则,转到下一个模块并重复该过程。您可以添加一段代码来执行
if
语句(类似于我添加的执行
generic_函数的过程)。顺便说一句,这应该是一个不同的问题。