Python: passing flags to functions

前端 未结 6 2110
清酒与你
清酒与你 2021-02-09 12:27

For a long time i have been trying to figure out what is the best way to pass flags to python functions. The most straightforward way is something like:

def func         


        
相关标签:
6条回答
  • 2021-02-09 12:54

    I prefer functions without flags. Rather do this:

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

    But "flagX" would actually be something meaningful like "do_X_with_option".

    I prefer this because it makes it clearer, you keep the functions simpler (fewer bugs), and you don't have to carry some constants into other modules (in the case of flags actually being some kind of enumeration).

    0 讨论(0)
  • 2021-02-09 12:58

    With *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')
    

    This is a good question to understand how *args and **kwargs work : *args and **kwargs?

    0 讨论(0)
  • 2021-02-09 13:05

    What about flipping it over?

    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])
    
    0 讨论(0)
  • 2021-02-09 13:11

    I am missing the good old bitwise flags:

    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
    
    0 讨论(0)
  • 2021-02-09 13:17

    Some Python standard libraries use this:

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

    You can tweak this approach by using *args:

    my.func(a, b, c, my.MULTLINE, my.IGNORECASE)
    

    I would really recommend going with flag1=True:

    • it is readable
    • flag name is checked at compile time (unless **kwargs is used)
    • you can use flag=1 and flag=0 instead of True and False to reduce the noise
    • you can temporarily change LONG_FLAG_NAME_YOU_DONT_REMEMBER=True to False without retyping the long name when you will need to change back
    0 讨论(0)
  • 2021-02-09 13:17

    you can define flag1 ...flagN as global variables, and define your function with func( *args)

    FLAG1 = 1
    FLAG2 = 2
    
    def func(*args):
       pass
    
    func(FLAG1, FLAG2)
    

    By defining flags separately, instead of using string, you can avoid typos in flags' names and some headache when debugging

    0 讨论(0)
提交回复
热议问题