2013-02-07 5 views
2

Я пытаюсь создать декоратор, который может проверять аргументы завернутой функции, контекст необходимости заключается в том, чтобы облегчить проверку определенных аргументов до того, как они нажмут на функцию, избегая плиты котла проверки в каждом месте мне нужна указанная проверка/валидация.Декоратор, который может взаимодействовать с аргументами завернутой функции

Это не трудно декоратор писать, хотя, и это получает работу (чтобы убедиться, что значение не является Ни для примера):

def check_arg(func): 
    def wrapped(value): 
     assert value is not None 
     func(value) 
    return wrapped 

Приведенный выше пример не код продукции, то просто пример того, что будет работать, но проблема становится очевидной, когда функция украшения может использовать другие декораторы.

В этом случае приведенный выше пример декоратора не будет работать, потому что теперь value может быть другим декоратором. Я мог бы добавить еще одну вложенную функцию здесь, но похоже, что должен быть более эффективный способ иметь дело с ней программно, плюс она будет ломаться всякий раз, когда меняется количество декораторов.

Как я могу получить аргументы обернутой функции независимо от количества используемых ею декораторов?

EDIT: Я должен был заметить, что я не просто укладываю декораторы, я использую один декоратор, который украшает повторно используемые декораторы. В приведенном выше примере я бы повторно использовать, что в этом контексте:

@check_arg 
def some_other_decorator(func): 
    def wrapped(*args, **kw): 
     ... # some interaction here 
    return wrapped 

Как я писал это изменение, я понял, что check_arg декоратор был в неправильном месте, он должен был быть в вызове функции wrapped в пределах some_other_decorator.

+1

Может быть, я запутался; не '' значение всегда будет аргументом, который пользователь поставил? 'func' может быть функцией, которая уже была обработана другим декоратором, но она все равно будет функцией, ожидающей того же типа аргумента, что и' wrapped', или вызов 'func' внутри' wrapped' не будет работать , Не могли бы вы привести пример кода, где ваш прототип не удается? – chepner

ответ

0

Вы управляете другими декораторами? Если да, то убедитесь, что все они играют хорошо, должным образом оберточной вызывающую функцию:

import functools 
    def check_arg(func): 
     @functools.wraps(func) 
     def wrapped(value): 
      assert value is not None 
      func(value) 
     return wrapped 
Смежные вопросы