Вопрос по default-value, return-value, python – python - возвращает значение по умолчанию

8

Я хочу имитировать поведение встроенных функций (например,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, если это имеет значение)

Ваш Ответ

1   ответ
14

чтобы обнаружить, что значение по умолчанию не установлено:

sentinel = object()

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

Это работает, потому что экземплярobject() всегда будетs идентификатор собственной памяти и, таким образом,is вернет True, только если точное значение осталось на месте.Любое другое значение не будет регистрироваться как один и тот же объект, в том числе.None

Вы'Увидим разные варианты вышеописанного трюка в разных проектах Python. Любой из следующих часовых также будет работать:

sentinel = []
sentinel = {}
Есть ли способ остановить проход людей в дозорных? Andy Hayden
@hayden: конечно нет, это питон. Вы обычно называете это_sentinel или аналогичный, чтобы пометить его как частный, но это нене мешать предприимчивым душам ломать все, импортируя их в любом случае. Конечно, в этом нет никакого смысла. Martijn Pieters
это намного проще, спасибо! Steve

Похожие вопросы