You could change the default value to a sentinel:
_sentinel = object()
def foo(a, optional=_sentinel):
if optional is _sentinel:
optional = 42
print "1 arg"
else:
print "2 args"
or by accessing it directly in the func_defaults
tuple:
def foo(a, optional=object()):
if optional is foo.func_defaults[0]:
optional = 42
print "1 arg"
else:
print "2 args"
but don't actually use that; that'll just serve to confuse those not familiar with standard function object attributes.
Yes, the _sentinel
object is introspectable and can be obtained still by a determined developer, but then again that same developer could just monkeypatch your function as well. :-)