Python 为文件夹中的每个脚本调用函数
是否有一种方法(仅使用python,即:不使用bash脚本或其他语言代码)来调用文件夹中每个脚本中的特定函数,而无需显式导入所有脚本 例如,假设这是我的结构: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 {}'
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_函数的过程)。顺便说一句,这应该是一个不同的问题。