Повысьте свой уровень программирования на Python (Бонус: *args **kwargs)… ..🔥

Будьте готовы! Он действительно содержит много кода.

Мне не нужно объяснять, почему это трудно понять. Это причина, по которой вы здесь (не ждите, что только код теории). Но действительно ли вам нужно писать декораторы?

Удовольствие от программирования на Python должно заключаться в том, чтобы видеть короткие, лаконичные, читаемые классы, которые выражают множество действий в небольшом объеме четкого кода, а не в пачках тривиального кода, который до смерти утомляет читателя. - Гудио ван Россум. (создатель питона)

Оглавление: (кликабельно)

  1. Что такое декораторы?
  2. Управляйте функциями Python.
    1. Назначьте функцию нескольким переменным.
    2. Создавайте функции внутри функции.
    3. Передать функцию в качестве параметра другим функциям.
    4. Функции могут возвращать другие функции.
  3. Как обозначать и использовать декораторы.
  4. Реальные примеры декораторов.
    1. Timer = ›Получить время выполнения функции.
    2. Deco =› Параллельно запускает функцию Python.
    3. ShowMe = ›Получить документацию по времени процессора и т. Д. Для функции Python. .
  5. Встроенные декораторы классов Python.
    1. @classmethod
    2. @staticmethod
    3. @property

Бонус: узнайте, как использовать *args & **kwargs

Декораторы - это не что иное, как функции, которые добавляют новые функции к существующим методам, не изменяя их.

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

Давайте посмотрим, что мы можем делать с функциями Python.

1. Назначьте функцию нескольким переменным.

>>> def func(x):
...     return x.upper()
>>> func("roar")
'ROAR'
>>> new_func = func  # Assign func to a variable.
>>> new_func("meow")
'MEOW'
>>> del func
# We can call the new_func even after deleting the func
>>> new_func("meow "*2)
'MEOW MEOW '

2. Создайте функции внутри функции. (Новое для C/C++ программистов.)

def factorial(n):
    """ 
    Calculates the factorial of n, 
    n => integer and n >= 0.
    """
    if type(n) == int and n >= 0:
        if n == 0:
            return 1
        else:
            return n * factorial(n-1) # Recursive Call
    else:
        raise TypeError("n should be an integer and n >= 0")

Какой дефект в приведенном выше коде?

factorial(10) проверяет тип 10,9,8,7,… рекурсивно, что не нужно. мы можем решить эту проблему элегантно, используя внутренние функции.

def factorial(n):
    """ 
    Calculates the factorial of n, 
    n => integer and n >= 0.
    """
    def inner_factorial(n):
        if n == 0:
            return 1
        else:
            return n * inner_factorial(n-1)
    if type(n) == int and n >=0:
        return inner_factorial(n)
    else:
        raise TypeError("n should be an integer and n >= 0")

Эй, ты можешь использовать здесь декоратор. хорошо, давайте подождем.

3. Передайте функцию в качестве параметра другим функциям.

import math
def sin_cos(func, var):
    print("Call this" + func.__name__ +"function")
    print(func(var))
sin_cos(math.sin, 60) # -0.3048106211022167
sin_cos(math.cos, 45) # 0.5253219888177297

4. Функции могут возвращать другие функции.

def sound(range):    
    """ 
    Args: range (Type of sound). (<class 'str'>)
    Return: function object of the sound (<class 'function'>)
    """ 
    def loud(x):
        print(x.upper() + '🐯')
    def low(x):
        print(x.lower() + '🐱')
    if range == 'loud':
        return loud
    else:
        return low
tiger = sound("loud") # you can use this as a functions.
tiger("roar..") # ROAR..🐯
cat = sound("low")
cat("MEOW..") # meow..🐱

Я тоже немного растерялся, когда увидел это впервые. Для каждого диапазона sound возвращает соответствующую функцию. Более полезный пример - создание многочлена степени n.

Ref: https://www.python-course.eu/python3_decorators.php#Functions-returning-Functions
def polynomial_creator(a, b, c):
    """
    Creates 2nd degree polynomial functions
    """
    def polynomial(x):
        return a * x**2 + b * x + c
    return polynomial
    
p1 = polynomial_creator(2, 3, -1)
p2 = polynomial_creator(-1, 2, 1)
x = -2
print(x, p1(x), p2(x)) # -2 1 -7

Краткое упражнение: попробуйте написать функцию, которая принимает в качестве аргументов степень и параметр и возвращает многочлен n-степени.

Закончив с Основами, отсюда будет сложно. (👀)

Начнем с простого декоратора, который выводит имя функции перед ее запуском.

🔥 Совет: используя *args, вы можете отправлять в функцию переменные различной длины. *args принимает его как кортеж. Узнать больше о *args и *kwargs

Синтаксис декораторов отличается от того, что мы выразили в приведенном выше примере. Обычно обозначается как @ (Чтобы украсить ваш код).

🔥 ProTip: Используя Code-Medium, вы можете создавать и редактировать GitHub Gists прямо из вашей средней статьи. (Как и выше).

Примечание. Когда вы завершаете функцию с помощью декоратора, атрибуты исходной функции, такие как __doc__ (docstring), __name __ (имя функции), __module __ (модуль, в котором определена функция), будут потеряны.

Хотя вы можете перезаписать их в функции декоратора, у Python есть встроенный декоратор @wraps для этого.

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

Чтобы лучше понять, давайте рассмотрим несколько реальных примеров декораторов.

  1. Таймер отслеживает время, затраченное функцией на выполнение.

🔥 Совет: вы можете получить доступ к исходной функции, развернув ее с помощью original_looper = looper.__wrapped__ (Предполагая, что вы использовали @wraps)

2. Deco: библиотека, которая автоматически распараллеливает программы Python Link.

Alex Sherman создал эту простую библиотеку под названием deco, которая позволяет функциям python работать параллельно, просто добавив декоратор круто, ага ..!

Функция, которую вы хотите запустить параллельно, украшена @concurrent
Функция, которая вызывает параллельную функцию, украшена @synchronized

@concurrent # We add this for the concurrent function
def process_lat_lon(lat, lon, data):
  #Does some work which takes a while
  return result

# And we add this for the function which calls the concurrent function
@synchronized
def process_data_set(data):
  results = defaultdict(dict)
  for lat in range(...):
    for lon in range(...):
      results[lat][lon] = process_lat_lon(lat, lon, data)
  return results

Совет от профессионалов 🔥: Аналогичная, но продвинутая библиотека научных вычислений для более быстрого запуска кода Python - это numba.

3. Showme: ShowMe - это простой набор чрезвычайно полезных декораторов функций для Python. Он позволяет просматривать информацию трассировки, время выполнения, время процессора и документацию по функциям. ССЫЛКА.

Распечатайте переданные аргументы и вызовы функций.

ref: https://github.com/navdeep-G/showme
@showme.trace
def complex_function(a, b, c, **kwargs):
    ...


>>> complex_function('alpha', 'beta', False, debug=True)
calling haystack.submodule.complex_function with
   args: ({'a': 'alpha', 'b': 'beta', 'c': False},)
   kwargs: {'debug': True}

Время выполнения функции печати.

@showme.time
def some_function(a):
    ...

>>> some_function()
Execution speed of __main__.some_function:
0.000688076019287 seconds

Время выполнения ЦП функции печати.

@showme.cputime
 def complex_function(a, b, c):
     ...

 >>> complex_function()
 CPU time for __main__.complex_function:
      3 function calls in 0.013 CPU seconds

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
     1    0.013    0.013    0.013    0.013 test_time.py:6(test)
     1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
     1    0.000    0.000    0.000    0.000 {range}

Ссылки на другие примеры находятся в разделе ссылок.

К настоящему времени вы получили представление о том, как работают декораторы, и создали свой собственный декоратор. давайте посмотрим на некоторые встроенные декораторы Python.

Популярные встроенные декораторы Python

@classmethod: Создает экземпляр класса. (Passclsnotself)

Пример: Предположим, вы получаете данные из разных типов данных, вместо того, чтобы создавать несколько классов, мы можем обработать их с помощью @classmethod.

@staticmethod: Вы можете использовать методы с этим декоратором, не создавая экземпляр класса. (Не нужно сдавать self)

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

@Property: способ использования команд get & set в ООП.

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

Каждый раз, когда вы вызываете set или get на maxlimit значение бокса, он проходит через @propertyи @maxlimit.setter.

Ссылки:
- Продвинутый Python от Бренда Кляйна.
- Если вам нравится питон, вы влюбитесь в Настоящий Python.
- Как работает @property подробно.
- Замечательные декораторы Python.

Я знаю, что это длинный, Но если ты добрался сюда 👏 к тебе. Продолжайте учиться, продолжайте расти.

свяжитесь со мной в LinkedIn или Github.