Search code examples
pythondefault-arguments

How to distinguish default argument and argument provided with default value?


Say I have function f as follows:

def f(c=None):
    return 42 if c is None else c

Then I can't get None out of this function. Now you could think "well, just check for another value like 2128.213 or whatever" but then I can't get that specific value out of the function can I?

That's why I'd like to distinguish, if possible, between f() and f(None) so that I can have

f() -> 42
f(None)-> None

Bear in mind this is a simplified example. In practice it's a class's __init__(...) function with multiple positional arguments which I'd like to handle as c in this example.


Solution

  • The common practice in such cases is to use specific sentinel value you never want to return.

    class Sentinel():
        pass
    
    
    _sentinel = Sentinel()
    
    # _sentinel = object()  # this is the option too
    
    def f(x=_sentinel):
        return 42 if x is _sentinel else x
    
    assert f() == 42
    assert f(None) is None
    assert f(5) == 5