Call function without optional arguments if they are None

前端 未结 9 1994
自闭症患者
自闭症患者 2020-12-29 02:00

There\'s a function which takes optional arguments.

def alpha(p1=\"foo\", p2=\"bar\"):
     print(\'{0},{1}\'.format(p1, p2))

Let me iterat

相关标签:
9条回答
  • 2020-12-29 02:32

    Not a direct answer, but I think this is worth considering:

    See if you can break your function into several functions, neither of which has any default arguments. Factor any shared functionality out to a function you designate as internal.

    def alpha():
        _omega('foo', 'bar')
    
    def beta(p1):
        _omega(p1, 'bar')
    
    def _omega(p1, p2):
         print('{0},{1}'.format(p1, p2))
    

    This works well when the extra arguments trigger "extra" functionality, as it may allow you to give the functions more descriptive names.

    Functions with boolean arguments with True and/or False defaults frequently benefit from this type of approach.

    0 讨论(0)
  • 2020-12-29 02:34

    Another possibility is to simply do alpha("FOO", myp2 or "bar"), but that requires us to know the default value. Usually, I'd probably go with this approach, but I might later change the default values for alpha and this call would then need to be updated manually in order to still call it with the (new) default value.

    Just create a constant:

    P2_DEFAULT = "bar"
    
    def alpha(p1="foo", p2=P2_DEFAULT):
         print('{0},{1}'.format(p1, p2))
    
    

    and call the function:

    alpha("FOO", myp2 or P2_DEFAULT)
    

    If default values for alpha will be changed, we have to change only one constant.

    Be careful with logical or for some cases, see https://stackoverflow.com/a/4978745/3605259

    One more (better) use case

    For example, we have some config (dictionary). But some values are not present:

    config = {'name': 'Johnny', 'age': '33'}
    work_type = config.get('work_type', P2_DEFAULT)
    
    alpha("FOO", work_type)
    

    So we use method get(key, default_value) of dict, which will return default_value if our config (dict) does not contain such key.

    0 讨论(0)
  • 2020-12-29 02:35

    But assume that alpha is used in other places where it is actually supposed to handle None as it does.

    To respond to this concern, I have been known to have a None-like value which isn't actually None for this exact purpose.

    _novalue = object()
    
    def alpha(p1=_novalue, p2=_novalue):
        if p1 is _novalue:
            p1 = "foo"
        if p2 is _novalue:
            p2 = "bar"
        print('{0},{1}'.format(p1, p2))
    

    Now the arguments are still optional, so you can neglect to pass either of them. And the function handles None correctly. If you ever want to explicitly not pass an argument, you can pass _novalue.

    >>> alpha(p1="FOO", p2=None)
    FOO,None
    >>> alpha(p1="FOO")
    FOO,bar
    >>> alpha(p1="FOO", p2=_novalue)
    FOO,bar
    

    and since _novalue is a special made-up value created for this express purpose, anyone who passes _novalue is certainly intending the "default argument" behavior, as opposed to someone who passes None who might intend that the value be interpreted as literal None.

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