Как я могу рассматривать позиционные аргументы как аргументы ключевого слова в Python 2

Для декоратора я написание Я хотел бы манипулировать определенным именованным параметром функции. Рассмотрим следующий декоратор:

def square_param(param):
    def func_decorator(func):
        def func_caller(*args,**kwargs):
            kwargs[param] = kwargs[param] * kwargs[param]
            return func(*args,**kwargs)
    return func_caller
return func_decorator

Применяется к следующей функции:

@square_param('dividend')
def quotient(divisor=1,dividend=0):
    return dividend/divisor

Это будет работать, если делимое вызывается как аргумент ключевого слова, например:

>>> quotient(dividend=2)
4

Однако, когда он задан как позиционный аргумент, это не сработает.

>>> quotient(3,4)
TypeError: quotient() got multiple values for keyword argument 'dividend'

С Python 3 Я мог бы решить эту проблему, заставив параметр всегда указывать как ключевое слово :

@square_param('dividend')
def quotient(divisor=1,*,dividend=0):
    return dividend/divisor

но я хотел бы поддерживать Python 2, а также хотел бы наложить небольшие ограничения на функцию.

Есть ли способ исправить это поведение в моем декораторе?

5
задан Peter Smit 5 July 2011 в 07:59
поделиться

1 ответ

Это может только быть мимоходом связано, но я нашел полезным решить подобную проблему. Я хотел объединиться *args и **kwargs в единственный словарь так, чтобы мой после кода мог обработать без учета к тому, как args вошел, и я не хотел видоизменять существующее kwargs переменная, иначе у меня просто будет использование kwargs.update().

all_args = {**kwargs, **{k: v for k, v in zip(list(inspect.signature(func).parameters), args)}}

# optionally delete `self`
del (all_args['self'])

Обновление : В то время как это работает, , этот ответ имеет лучшую технику. Частично:

bound_args = inspect.signature(f).bind(*args, **kwargs)
bound_args.apply_defaults()
0
ответ дан 14 December 2019 в 18:20
поделиться
Другие вопросы по тегам:

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