Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
427 views
in Technique[技术] by (71.8m points)

python - returning a default value

I'm looking to mimic the behavior of built-in functions (like getattr) that allow the user to specify a "default" return value. My initial attempt was to do this

def myfunc(foo, default=None):
    # do stuff
    if (default is not None):
        return default
    raise SomeException()

The problem is that if the users wants None to be their return value, this function would instead raise an exception. second attempt:

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

This addresses the above issue and allows the user to specify any arbitrary value, but introduces an annoyance in that the user must always specify default=bar in their function calls; they can't just provide bar at the end. Likewise, *args could be used, but prevents users from using default=bar if they prefer that syntax.

Combining *args and **kwargs provides a workable solution, but it feels like this is going to a lot of effort. It also potentially masks improper function calls (eg 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()

Is there a simpler solution? (python 3.2 if that matters)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You need to use a sentinel to detect that a default value was not set:

sentinel = object()

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

This works because an instance of object() will always have it's own memory id and thus is will only return True if the exact value was left in place. Any other value will not register as the same object, including None.

You'll see different variants of the above trick in various different python projects. Any of the following sentinels would also work:

sentinel = []
sentinel = {}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...