Идиоматический способ указания аргументов по умолчанию, чье присутствие / отсутствие присутствия имеют значение

Я часто вижу код Python, который принимает аргументы по умолчанию и имеет специальное поведение, когда они не указаны.

Если я например хочу поведение, подобное этому:

def getwrap(dict, key, default = ??):
    if ???: # default is specified
        return dict.get(key, default)
    else:
        return dict[key]

Если бы я катился сам, я бы в итоге получил что-то вроде:

class Ham:
    __secret = object()
    def Cheese(self, key, default = __secret):
        if default is self.__secret:
            return self.dict.get(key, default)
        else:
            return self.dict[key]

Но я не хочу придумывать что-то глупое, когда, конечно, есть стандарт. Какой идиоматический способ сделать это в Python?

2 ответа

Решение

Я обычно предпочитаю

def getwrap(my_dict, my_key, default=None):
    if default is None:
        return my_dict[my_key]
    else:
        return my_dict.get(my_key, default)

но, конечно, это предполагает, что None никогда не является допустимым значением по умолчанию.

Вы можете сделать это на основе *args и / или**kwargs,

Вот альтернативная реализация getwrap основанный на *args:

def getwrap(my_dict, my_key, *args):
    if args:
        return my_dict.get(my_key, args[0])
    else:
        return my_dict[my_key]

И вот оно в действии:

>>> a = {'foo': 1}
>>> getwrap(a, 'foo')
1
>>> getwrap(a, 'bar')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in getwrap
KeyError: 'bar'
>>> getwrap(a, 'bar', 'Nobody expects the Spanish Inquisition!')
'Nobody expects the Spanish Inquisition!'
Другие вопросы по тегам