很长一段时间以来,我一直试图弄清楚将标志传递给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风格的标志要容易得多,而且要容易得多。标志基本上是静态检查的,非常清晰/干净。现在,如果我能剃除最后两个角色......
答案 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:
答案 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>