python - 返回默认值

Ste*_*eve 10 python return-value default-value

我希望模仿内置函数(如getattr)的行为,允许用户指定"默认"返回值.我最初的尝试就是这样做

def myfunc(foo, default=None):
    # do stuff
    if (default is not None):
        return default
    raise SomeException()
Run Code Online (Sandbox Code Playgroud)

问题是,如果用户想要None成为他们的返回值,则此函数会引发异常.第二次尝试:

def myfunc(foo, **kwargs):
    # do stuff
    if ('default' in kwargs):
        return kwargs['default']
    raise SomeException()
Run Code Online (Sandbox Code Playgroud)

这解决了上述问题并允许用户指定任意值,但引入了一个烦恼,即用户必须始终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()
Run Code Online (Sandbox Code Playgroud)

有更简单的解决方案吗?(如果重要,则为python 3.2)

Mar*_*ers 16

您需要使用标记来检测未设置默认值:

sentinel = object()

def func(someparam, default=sentinel):
    if default is not sentinel:
        print("You passed in something else!")
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为一个实例object()将始终拥有它自己的内存ID,因此is只有在准确值保留的情况下才会返回True.任何其他值都不会注册为同一个对象,包括None.

您将在各种不同的python项目中看到上述技巧的不同变体.以下任何哨兵也会奏效:

sentinel = []
sentinel = {}
Run Code Online (Sandbox Code Playgroud)

  • @hayden:当然不是,这是python.你通常把它命名为`_sentinel`或类似的把它标记为私有,但这并不能阻止进取的灵魂通过导入来破坏一切.当然,没有必要这样做. (2认同)