【问题标题】:How can I achieve override a function call in the middle of another function?如何在另一个函数中间实现覆盖函数调用?
【发布时间】:2018-03-11 10:54:55
【问题描述】:

我正在编写一个 Python3 程序,我需要能够在其中动态覆盖某些方法。我的文件夹结构更像:

./
prog.py
methods/
  add.py
  minus.py

prog.py 中,我想调用在add.pyminus.py 中定义的calc() 函数。我希望代码可以像这样工作:

def prog('foo'):
    from method.foo import calc
    calc()

但是在函数中间导入看起来很糟糕,可能会减慢整个程序的速度。有没有什么办法可以达到同样的效果?

我试图变得灵活,以便以后可以添加更多方法,因此我避免使用 if 语句并一次导入所有模块。

【问题讨论】:

  • 是否有什么东西阻止你只调用 if 语句分支中的函数,还是比示例显示的更复杂?
  • 不,但我正在考虑不时添加不同的 calc()。实际上,我希望在不使用 if 语句的情况下实现 prog(add) 导入 method.add。我会修改我的问题...@BHustus
  • 哦,所以您希望能够从某个路径动态加载模块?
  • 如果你想动态导入一些东西,有一些方法可以在运行时做到这一点。我不打算将此作为正式答案发布,因为我没有对此进行测试,我不建议从表面上看我的话,但请查看importlib.import_module 并明智地使用del,看看是否可以你需要什么。
  • 这是正确的......不会造成麻烦。:) @BHustus

标签: python import python-import


【解决方案1】:

你有两个选择:

  • 导入模块,并使用带有calc属性的模块名称。
  • 使用 from ... import ... as 以备用名称导入 calc 函数

无论哪种方式,我都会将函数引用存储在字典中,而不是使用if .. elif 来选择一个。

第一种方法

from method import add
from method import minus

calc_functions = {
    'add': add.calc,
    'minus': minus.calc,
}

def prog(method):
    return calc_functions[method]()   

或第二个:

from method.add import calc as addition
from method.minus import calc as subtraction

calc_functions = {
    'add': addition,
    'minus': subtraction,
}

def prog(method):
    return calc_functions[method]()   

如果您需要动态地导入模块,则使用importlib.import_module(),无需担心名称冲突:

import importlib

def prog(method):
    try:
        calc_module = importlib.import_module('method.' + method)
    except ModuleNotFoundError:   # or ImportError in Python < 3.6
        raise ValueError('No such method {!r}'.format(method))
    return calc_module.calc()

    return calc_functions[method]()   

【讨论】:

  • 这很简洁,但就我而言,每次添加一些新的 calc() 方法时都需要更改代码。可以动态做吗?
  • @7O'clock: 可以,可以动态导入模块,见Dynamic module import in Python
猜你喜欢
  • 2017-06-25
  • 2010-10-25
  • 2013-10-31
  • 1970-01-01
  • 2014-09-08
  • 1970-01-01
  • 2022-12-04
  • 2011-05-02
  • 1970-01-01
相关资源
最近更新 更多