实现选择标志的Python方式

问题描述

我在一个python模块上工作,其中超过3/4的函数提供6个选项的选择,并且相应地表现不同。 1

我的目标是使此参数的使用尽可能简单,明显和易读,以及(虽然不那么重要)实现它。

实现这种标记的最Python方式是什么?

我看到的方式有3种选择:

1。为每个组件使用字符串标识符(当前解决方案):
+ 用法简单易读,没有其他导入,类,实现详细信息
-:字符串比较不灵活,用户必须知道字符串(没有编辑器帮助)

# in module/__init__.py
E_X = 'e_x'
E_Y = 'e_y'
...

# in module/whatever.py:
def do_sg(args,comp):
    if comp == E_X:
        set_some_state_for_ex()
        res = calc_sg_with_ex(args)
    elif comp == E_Y:
        ...
    return res

# usage
from module.whatever import do_sg
res = do_sg(args,'e_r')

2:使用模块范围的常量:
+ 文字定义,编辑提示
-:使用更加晦涩难懂,名称空间受到污染(避免使用更晦涩的名称),没有容易的方法来导入所有组件

# in module/__init__.py
E_X_COMP = 1
E_Y_COMP = 2
...

# in module/whatever.py,implementation v1
from . import *
def do_sg(args,comp):
    if comp == E_X_COMP:
        set_some_state_for_e_x()
        res = calc_sg_with_e_x(args)
    elif comp == E_Y_COMP:
        ...
    return res

# usage ( (1) may be used this way as well)
import module   # or from module import E_X_COMP,E_Y_COMP,...
from module.whatever import do_sg
res = do_sg(args,module.E_X_COMP)

# or more obscurely:
res = do_sg(args,0)

3:使用Enum类:
+ :封闭的文字定义,比常量更明显的用法,更好的编辑器提示,类型提示
-:与字符串标识符相比,实现更模糊,模块依赖性更大,导入和对象更多

# in module/__init__.py
from enum import Enum
class component(Enum):
    e_x = 1
    e_y = 2
    ...

# in module/whatever.py,implementation v1
from . import component
def do_sg(args,comp):
    if comp is component.e_x:
        res = calc_sg_with_e_x(args)
    elif comp is component.e_y:
        ...
    return res

# usage
from module import component
from module.whatever import do_sg
res = do_sg(args,component.e_x)

4:其他选项?

还有其他我没有考虑的方法吗?


1:更具体地说,该模块用于计算电磁场的分量,并且可以选择要考虑的分量-可以是E和B场的x,y和z分量。向量实现由于各种原因而无法正常工作。

解决方法

Enum正是针对此类问题而创建的。还应该将它们视为常量,因此适当的命名将有所帮助:

class Component(Enum):
    E_X = 1
    E_Y = 2

正在使用;

from module import Component
from module.whatever import do_sg
res = do_sg(args,Component.E_X)
,

这很有趣,因为我喜欢谈论代码样式。我不知道您确切想做什么,但是似乎以一种简洁的方式实现了switch。如果您是我,则不会使用任何(global)常量。它们总是使代码的可读性降低。

一种使代码更具可读性的方法,我认为您可以将if-else块定义为函数,并直接使用函数而不是使用外部作用域常量进行分支。例如:

# in module/whatever.py,implementation v1
from . import *
class do_sg:
    @classmethod
    def e_x(args):
        set_some_state_for_e_x()
        res = calc_sg_with_e_x(args)
        return res

    @classmethod
    def e_y(args):
        ...
        return res

# usage
from module.whatever import do_sg
res = do_sg.e_x(args)