Python条件导入的设计

2024-04-24 23:48:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我不熟悉Python中的条件导入,正在考虑两种模块设计方法。如果你能告诉我为什么我会选择一个而不是另一个(或者是否有更好的选择)

问题

我有一个程序,需要在不同的条件下调用结构相同但不同的模块。这些模块都有相同的功能、输入、输出等,唯一的区别在于它们在各自的功能中做了什么。例如

# module_A.py
def get_the_thing(input):
    # do the thing specific to module A
    return thing

# module_B.py
def get_the_thing(input):
    # do the thing specific to module B
    return thing

方案1

基于一个输入值,我将有条件地导入适当的模块,与this answer保持一致

if val == 'A':
    import module_A
if val == 'B':
    import module_B

方案2

我使用输入变量以字符串的形式生成模块名,然后基于该字符串使用this method从正确的模块调用函数。我相信这需要我先导入所有模块

import module_A
import module_B

in_var = get_input() # Say my input variable is 'A', meaning use Module A
module_nm = 'module_' + in_var
function_nm = 'get_the_thing'

getattr(globals()[module_nm], function_nm)(my_args)

其思想是在运行时通过生成模块和函数名来调用模块\u A.get\u The \u thing()。对于一个函数调用来说,这是一个很无聊的例子,但是在我的实际例子中,我使用的是一系列函数,只是希望保持简单

关于这两种设计是否更好,或者是否存在优于这两种设计的东西有什么想法吗?如果有任何理由为什么,我们将不胜感激。当然,A更简洁,可能更直观,但不确定这是否一定等同于良好的设计或性能上的差异


Tags: 模块thetopyimport功能inputget
1条回答
网友
1楼 · 发布于 2024-04-24 23:48:37

我会选择选项1。它明显更整洁,而且你不需要摆弄字符串来进行查找。处理字符串至少会使重构复杂化。如果您更改了任何涉及的名称,您必须记住更新字符串;尤其是因为即使是智能ide也无法在这里帮助您进行典型的shift+F6重命名。这样的代码维护困难的地方越少越好

不过,我会把它改成1。根据您现在的情况,模块的每次使用仍然需要使用限定名,如module_A.do_thing()。这意味着,无论何时调用函数,都需要首先找出导入的函数,这会导致代码更加混乱。我会用一个共同的名字导入它们:

if val == 'A':
    import module_A as my_module

if val == 'B':
    import module_B as my_module

. . .

my_module.do_thing()  # The exact function called will depend on which module was imported as my_module

您还可以按照注释中的建议,使用通配符导入,以避免需要为模块使用名称:

if val == 'A':
    from module_A import *

if val == 'B':
    from module_B import *

. . .

do_thing()

但是PEP8不鼓励这样做:

Wildcard imports (from <module> import *) should be avoided, as they make it unclear which names are present in the namespace, confusing both readers and many automated tools.

它还污染了要导入的名称空间,从而更容易意外地从导入的文件中隐藏名称

相关问题 更多 >