Python:将标志传递给函数

Li *_*oyi 7 python

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

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

func(my_data, True, False, True)
Run Code Online (Sandbox Code Playgroud)

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

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

func(my_data, flag1=True, flag3=True)
Run Code Online (Sandbox Code Playgroud)

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

func(mydata, ['flag1', 'flag3'])
Run Code Online (Sandbox Code Playgroud)

要么

func(mydata, [func.flag1, func.flag3])
Run Code Online (Sandbox Code Playgroud)

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

func(my_data, flag1, flag3)
Run Code Online (Sandbox Code Playgroud)

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

编辑:我最终去了:

func(mydata, flagA=1, flagB=1)
Run Code Online (Sandbox Code Playgroud)

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

def func(data, flagA=1, flagB=0, flagC=1):
    ...
Run Code Online (Sandbox Code Playgroud)

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

Jak*_* M. 5

你可以定义flag1... flagN作为全局变量,并定义你的函数func( *args)

FLAG1 = 1
FLAG2 = 2

def func(*args):
   pass

func(FLAG1, FLAG2)
Run Code Online (Sandbox Code Playgroud)

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


Ric*_*kyA 5

我错过了旧的按位标志:

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
Run Code Online (Sandbox Code Playgroud)


ham*_*ene 4

一些 Python 标准库使用这个:

re.match(pattern, str, re.MULTILINE | re.IGNORECASE)
Run Code Online (Sandbox Code Playgroud)

您可以使用 *args 来调整此方法:

my.func(a, b, c, my.MULTLINE, my.IGNORECASE)
Run Code Online (Sandbox Code Playgroud)

我真的建议使用 flag1=True :

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