我希望模仿允许用户指定“默认”返回值的内置函数(如getattr
)的行为。我最初的尝试就是这样做
def myfunc(foo, default=None):
# do stuff
if (default is not None):
return default
raise SomeException()
问题是,如果用户希望None
成为他们的返回值,则此函数会引发异常。第二次尝试:
def myfunc(foo, **kwargs):
# do stuff
if ('default' in kwargs):
return kwargs['default']
raise SomeException()
这解决了上述问题并允许用户指定任意值,但引入了一个烦恼,即用户必须始终在其函数调用中指定default=bar
;他们最后不能只提供bar
。同样,可以使用*args
,但如果他们更喜欢这种语法,则会阻止用户使用default=bar
。
结合*args
和**kwargs
提供了一个可行的解决方案,但感觉这需要付出很多努力。它还可能掩盖不正确的函数调用(例如bar = myfunc(foo, baz, default=qux)
)
def myfunc(foo, *args, **kwargs):
# do stuff
if (len(args) == 1):
return args[0]
if ('default' in kwargs):
return kwargs['default']
raise SomeException()
有更简单的解决方案吗? (如果重要,则为python 3.2)
答案 0 :(得分:15)
您需要使用标记来检测未设置默认值:
sentinel = object()
def func(someparam, default=sentinel):
if default is not sentinel:
print("You passed in something else!")
这是有效的,因为object()
的实例将始终拥有它自己的内存ID,因此is
只有在准确值保留的情况下才会返回True。 任何其他值都不会注册为同一个对象,包括None
。
您将在各种不同的python项目中看到上述技巧的不同变体。以下任何哨兵都可以使用:
sentinel = []
sentinel = {}