Python – декораторы

Я пытаюсь изучить Decorators . Я понял ее концепцию и теперь пытаюсь ее реализовать.

Вот код, который я написал . Код не требует пояснений. Он просто проверяет, прошел ли аргумент в int или нет.

 def wrapper(func): def inner(): if issubclass(x,int): pass else: return 'invalid values' return inner() @wrapper def add(x,y): return x+y print add('a',2) 

Это ошибка, говорящая, что global name 'x' is not defined . Я понимаю, что он не определяется под inner , но не знает, как исправить этот код? Где я ошибаюсь?

  • Как создать цепочку декораторов функций?
  • как сделать условный декоратор в python 2.6
  • У вас возникли проблемы с изготовлением декоративного декоратора django (с помощью args)
  • Как сделать декораторы необязательно включать или выключать
  • Поймать события «до / после вызова функции» для всех функций класса
  • Объем переменных в декораторе python
  • Флакон: Декоратор для проверки схемы JSON и JSON
  • Как использовать декораторы Python для проверки аргументов функции?
  • 5 Solutions collect form web for “Python – декораторы”

    Ваш декоратор должен выглядеть так:

     def wrapper(func): def inner(x, y): # inner function needs parameters if issubclass(type(x), int): # maybe you looked for isinstance? return func(x, y) # call the wrapped function else: return 'invalid values' return inner # return the inner function (don't call it) 

    Некоторые моменты:

    • issubclass ожидает класс как первый аргумент (вы можете заменить его простой try / except TypeError).
    • оболочка должна возвращать функцию, а не результат вызываемой функции
    • вы должны фактически называть обернутую функцию во внутренней функции
    • у вашей внутренней функции не было параметров

    Здесь вы можете найти хорошее объяснение декораторов.

    Есть три вопроса, которые я вижу с вашим текущим кодом.

    Во-первых, вы вызываете inner функцию, а не возвращаете ссылку на нее.

    Во-вторых, ваша inner функция не принимает те же аргументы, что и функция, которую вы украшаете. В этом случае вам нужно явно принять хотя бы аргумент x (некоторые внутренние функции могут использовать *args и **kwargs исключительно, но, скорее, не ваши).

    Наконец, вы никогда не вызываете завернутую функцию. Хотя это не является строго обязательным (полезно было бы поменять метод с декоратором во время разработки), обычно вы хотите вызвать функцию в какой-то момент во время кода внутренней функции.

    Итак, чтобы объединить все это, я думаю, вы хотите, чтобы ваш код был примерно таким:

     def wrapper(func): def inner(x, y): if issubclass(x, int): # issue 2 return func(x, y) # issue 3 else: return "invalid values" # consider raising an exception here instead! return inner # issue 1 

    это может сработать.

    def wrapper(func): def inner(*args,**kwargs): if ((args[0] is int) and (args[1] is int)): pass else: return 'invalid values' return inner @wrapper def add(x,y): return x+y print add('a',2)

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

     def check_int_types(func): def type_checker(x, y): if issubclass(type(x), int) and issubclass(type(y), int): return func(x, y) raise Exception("Invalid types: {}, {}".format(x, y)) return type_checker @check_int_types def add(a, b): return a + b def main(): x = y = 15.0 print add(x, y) if __name__ == '__main__': main() 

    Результат:

     Traceback (most recent call last): File "deco_test.py", line 17, in <module> main() File "deco_test.py", line 14, in main print add(x, y) File "deco_test.py", line 5, in type_checker raise Exception("Invalid types: {}, {}".format(x, y)) Exception: Invalid types: 15.0, 15.0 

    Как насчет этого .

     def wrapper(func): def inner(): if isinstance(func,int): return func(x, y) else: return 'invalid values' return inner() 
    Python - лучший язык программирования в мире.