Python:将标志传递给函数

时间:2011-08-12 05:35:15

标签: python

很长一段时间以来,我一直试图弄清楚将标志传递给python函数的最佳方法是什么。最简单的方法是:

def func(data, flag1, flag2, flag3):
    ...

func(my_data, True, False, True)

这非常简洁,但难以理解,因为单词“True”或“False”不会告诉你什么标志正在设置,你必须仔细计算从左边开始的参数。您可以将它们设为关键字参数:

def func(data, flag1=False, flag2=False, flag3=False):
    ...

func(my_data, flag1=True, flag3=True)

但这有点多余,因为“真实”根本没有任何意义。我可以将它作为列表传递:

func(mydata, ['flag1', 'flag3'])

func(mydata, [func.flag1, func.flag3])

但是第一个感觉相当脏,使用字符串作为标志,第二个仍然有点重复。理想情况下,我想说的是:

func(my_data, flag1, flag3)

将标志传递给具有最小详细程度和冗余的函数。有没有办法在python中做这样的事情?

编辑: 我最终选择了:

func(mydata, flagA=1, flagB=1)

主要是出于上述原因:编译时检查(与传入字符串相比),没有命名空间污染(与使用全局“ENUM”相反)和最小样板(= 1或= 0只有2个字符,vs 5或6表示= True或= False)。它还可以非常轻松地设置标志的默认值:

def func(data, flagA=1, flagB=0, flagC=1):
    ...

这比跳过箍提取并将默认值分配给** kwarg风格的标志要容易得多,而且要容易得多。标志基本上是静态检查的,非常清晰/干净。现在,如果我能剃除最后两个角色......

6 个答案:

答案 0 :(得分:5)

您可以将flag1 ... flagN定义为全局变量,并使用func( *args)定义您的函数

FLAG1 = 1
FLAG2 = 2

def func(*args):
   pass

func(FLAG1, FLAG2)

通过单独定义标志,而不是使用字符串,可以避免在标志名称中出现拼写错误,并在调试时遇到一些麻烦

答案 1 :(得分:3)

使用* args:

def some_func(data, *args):
    # do something
    return args # this is just to show how it works


>>> print some_func(12, 'test', 'test2', 'test3')
('test', 'test2', 'test3')

这是一个很好的问题,可以理解* args和** kwargs是如何工作的:*args and **kwargs?

答案 2 :(得分:3)

一些Python标准库使用它:

re.match(pattern, str, re.MULTILINE | re.IGNORECASE)

您可以使用* args:

调整此方法
my.func(a, b, c, my.MULTLINE, my.IGNORECASE)

我真的建议使用flag1 = True:

  • 可读
  • 在编译时检查标志名称(除非使用** kwargs)
  • 您可以使用flag = 1和flag = 0代替True和False来降低噪音
  • 您可以暂时将LONG_FLAG_NAME_YOU_DONT_REMEMBER = True更改为False,而无需在需要更改时重新输入长名称

答案 3 :(得分:3)

把它翻过来怎么样?

flag1, flag2, flag3, flag4, flag5, flag6 = range(6)

def func(enable=[], disable=[],
         enabled_by_default=[flag5, flag6]):
    enabled = set(enabled_by_default + enabled) - set(disabled)
    if flag1 in enabled:
        ...
    if flag2 in enabled:
        ...

func(enable = [flag1, flag2, flag3],
     disable = [flag6])

答案 4 :(得分:3)

我错过了旧的bitwise标志:

a = 1
b = 2
c = 4
d = 8

def func( data, flags ):
    print( ( flags & a) == a )
    print( ( flags & b) == b )
    print( ( flags & c) == c )
    print( ( flags & d) == d )

>>>> func("bla", a|c|d)
>>>> True
>>>> False
>>>> True
>>>> True

答案 5 :(得分:-1)

我更喜欢没有旗帜的功能。而是这样做:

def func_flag1(arg):
    pass # something useful

def func_flag2(arg):
    pass # something for flag 2.

但是“flagX”实际上会像“do_X_with_option”那样有意义。

我更喜欢这个,因为它使它更清晰,你保持函数更简单(更少的bug),你不必将一些常量携带到其他模块中(在flags实际上是某种枚举的情况下)。 / p>