Вопрос по 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() всегда будет иметь свой собственный идентификатор памяти и, таким образом,is вернет True, только если точное значение осталось на месте.Any other value не будет регистрироваться как один и тот же объект, в том числеNone.

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

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

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