11

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)

4

1 回答 1

17

您需要使用哨兵来检测未设置默认值:

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 = {}
于 2012-09-04T14:33:23.930 回答