Python:如何让导入的模块调用本地定义的函数?
问题描述
我有一个脚本myScript.py,它既使用自身定义的函数(如printStatements()),也导入同一目录下config.py文件中的函数(如myTask())。我希望导入的myTask()函数能够调用本地定义的printStatements()函数,但运行时出现NameError: name 'printStatements' is not defined错误。由于不同脚本的打印行为不同,每个使用config.py的脚本都有自己的printStatements()函数,因此无法将该函数导入config.py中。
示例代码:
config.py
def myTask(m, x, c): y = (m*x) + c printStatements("y: {}".format(y))
myScript.py
import config as cnfg def printStatements(mymsg): print(mymsg) cnfg.myTask(3, 2, 4)
错误信息:
NameError: name 'printStatements' is not defined.
原因分析
config.py中的myTask函数运行在自身模块的命名空间里,默认无法访问myScript.py中定义的printStatements函数——两个函数分属不同模块的命名空间,没有显式关联的话无法互相调用。
解决方案
方法1:将本地函数作为参数传递给myTask
修改config.py的myTask,让它接受一个打印函数作为参数,这是最清晰低耦合的方案:
# config.py def myTask(m, x, c, print_func): y = (m*x) + c print_func("y: {}".format(y))
在myScript.py调用时,把本地的printStatements传入:
# myScript.py import config as cnfg def printStatements(mymsg): print(mymsg) cnfg.myTask(3, 2, 4, printStatements)
方法2:设置默认参数兼容原有调用(可选)
如果需要兼容其他未自定义打印函数的调用场景,可以给print_func设置默认值为系统自带的print:
# config.py def myTask(m, x, c, print_func=print): y = (m*x) + c print_func("y: {}".format(y))
这样其他脚本无需传参也能正常调用,有自定义需求时再传入自己的打印函数。
方法3:动态注入函数到config模块(不推荐)
如果不想修改myTask的参数结构,可以把本地函数注入到config模块的命名空间中,但这种方式会提升模块耦合度,仅适合简单场景:
# myScript.py import config as cnfg def printStatements(mymsg): print(mymsg) # 将本地函数注入config模块的命名空间 cnfg.printStatements = printStatements cnfg.myTask(3, 2, 4)
总结
优先选择方法1,通过传递函数参数实现回调,既保证了模块独立性,又能满足不同脚本自定义打印行为的需求,是最合理的解决方案。
内容的提问来源于stack exchange,提问作者DeltaKilo

