What are Python decorators?

- , . : Java, C#, PHP, JS. Python - .

. , , . , . . , .

Python - , . , . , . .

Python - , . , .

Python decorator




, . , , : , , .





"" - , def. , tab. , () . “:”.

"" , . pass.

def empty_func():

    pass
      
      



, . :

func = lambda x, y: x + y
      
      



:

func(1, 2,) # 3

      
      



( ):

(lambda x, y: x + y)(1, 2) # 3
      
      



:

@ 
    def _
         _
      
      



:

def decorator(change_funct):
    def return_func1():
        print “code before”
        change_funct()
        print “code after”
    return return_func1
      
      



, :

@decorator
def retrurn_func1():
    print new_change
      
      



Python .

Decorator in simple words




. , , .









  1. .
  2. .
  3. .
  4. .

. .

def bigger(a,b):
    if a > b:
        print a
    else:
        print b
      
      



:

bigger(5,6)
      
      



:

bigger(3)
bigger(12,7,3)
      
      



, , -.

def person(name, age):
    print name, "is", age, "years old"
    person(age=23, name="John")
      
      



, .

def space(planet_name, center="Star"):
    print(planet_name, "is orbiting a", center)
space("Mars")
      
      



, . :

def func(*args):
    return args
func(1, 2, 3, 'abc')
# (1, 2, 3, 'abc')
func(1)
#(1,)
      
      



- “**”.

, , , . global.

def get_older():
    global age
    age += 1
      
      



.

def fact(num):
    if num == 0:
        return 1
    else:
        return num * fact(num - 1)
      
      



.

Decorator function




, .

func()
      
      



“.” , .

object.func()
      
      



, Python , .

def method_friendly_decorator(method_to_decorate):

def wrapper(self, lie):
    lie = lie - 3 # 
    return method_to_decorate(self, lie)
return wrapper
      
      



F , ^

class Lucy(object):
    def __init__(self):
       self.age = 32

@method_friendly_decorator
    def sayYourAge(self, lie):
        print " %s,     ?" % (self.age + lie)

Lucy.sayYourAge(-32)
# 26,     ?
      
      



format(). , :

print(“string {} {}).format(1, 2)
#string 1 2​
      
      



format() : 1, 2. {} , . . , {}, - , . format . .

:

print(“string {} {}).format(1, 2)
#string 1 2
      
      



:

print(“string {1} {0}).format(1, 2)
#string 2 1
      
      



format(arg1 = value1, arg2 = value2).

print(“string {arg1} {arg2}).format(arg1 = 1, arg2 = 2)
#string 1 2
      
      



- . .

print(“string {arg1} {1}).format(arg1 = 1, 2)
#string 1 2
      
      



Python , .

def decorator(function_to_decorate):
    def function(arg1, arg2):
        print ",   :", arg1, arg2
    return function
      
      



@decorator, function. , function_to_decorate.

:

@decorator
    def real_func(, )
        print “ ”, arg1, arg2
      
      



:

,   : , 

   
      
      



, . , . :

@AAA
@BBB
@CCC
def function(...):
pass:
      
      



, AAA(), BBB(), , CCC().

def f():
    pass:

f = (AAA(BBB(CCC(function))):
      
      



Function , f(). , , , . , , function().

Python .

@firsdecorator

@seconddecorator

class CDC:

    pass:

C = firstdecorator(seconddecorator(CDC))

XX = C()

def fn1(arg): return lambda: 'XX' + arg()

def fn2(arg): return lambda: 'YY' + arg()

def fn3(arg): return lambda: 'ZZ' + arg()

@fn1

@fn2

@fn3

def myfunc(): # myfunc = fn1(fn2(fn3(myfunc)))

    return 'Python'
    
print(myfunc()) #  "XXYYZZPython"
      
      



def lambda:

lambda: 'XX' + arg()
      
      



Fn3() myfunc, ZZPython Python. fn2(), YYZZPython. fn1() myfunc() - XXYYZZPython.

Python. , .

Staticmethod - , static.

class C:

@staticmethod

    def f(arg1, arg2, ...): #static
    
        pass
      
      



Classmethod .

class MyClass:

@classmethod

def method(cls, arg):

print('%s classmethod. %d' % (cls.__name__, arg))

@classmethod

def call_original_method(cls):

cls.method(5)

def call_class_method(self):

    self.method(10)

class MySubclass(MyClass):

@classmethod

    def call_original_method(cls):

    cls.method(6)


MyClass.method(0) # MyClass classmethod. 0

MyClass.call_original_method() # MyClass classmethod. 5

MySubclass.method(0) # MySubclass classmethod. 0

MySubclass.call_original_method() # MySubclass classmethod. 6

#     .

my_obj = MyClass()

my_obj.method(1)

my_obj.call_class_method()
      
      



.

property , , .

class property([fget[, fset[, fdel[, doc]]]])
      
      



TypeScript :

Getters and Setters




Python. property :

  • fget - ;
  • fset ;
  • fdel ;
  • doc . doc , fget(), .
class C(object):

    def __init__(self):

        self._x = None

        def getx(self):

    return self._x

    def setx(self, value):

        self._x = value

    def delx(self):

        del self._x

x = property(getx, setx, delx, "I'm the 'x' property.")
      
      



Pythonproperty:

class C(object):

    def __init__(self):

        self._x = None

@property

def x(self):

    """I'm the 'x' property."""

    return self._x

    @x.setter

        def x(self, value):

        self._x = value
 
    @x.deleter

        def x(self):

        del self._x
      
      



Property x . setter, getter, deletter, .

:

  1. .
  2. . . , . .
  3. - , , . functools.

functools - , , Python.

Python functuls




cmp_to_key(func) cmp() key(). , " 3.0", 2. Lru_cache . maxsixe none, . . typed=true, . , typed=true, .

Total_ordering , , .

Partial(func, *args, **keywords) , , *args, , kwargs.

Reduce :

reduce(lambda x, y: x+y, [1, 2, 3, 4, 5])
      
      



:

((((1+2)+3)+4)+5)
      
      



Reduce , **keywords, *args. , lambda function :

1+2
      
      



, ..

Update_wrapper , . , .

assigned=WRAPPER_ASSIGNMENTS
      
      



WRAPPER_ASSIGNMENTS __name__, __module__, __annotations__ __doc__.

updated=WRAPPER_UPDATES
      
      



WRAPPER_UPDATES , , __dict__.

Wraps partial .

, , - .

Error in python




:

import functools def retry(func): @functools.wraps(func) def wrapper(*args, **kwargs): while True: try: return func(*args, **kwargs) except Exception: pass return wrapper​
      
      



, .

@retry def do_something_unreliable(): if random.randint(0, 10) > 1: raise IOError("Broken sauce, everything is hosed!!!111one") else: return "Awesome sauce!" print(do_something_unreliable())
      
      



, 9 11 .

def my_decorator(fn): def wrapped(): try: return fn() except Exception as e: print("Error:", e) return wrapped @my_decorator def my_func(): import random while True: if random.randint(0, 4) == 0: raise Exception('Random!') print('Ok') my_func()
      
      



:

Ok Ok Ok Error: Random! 
      
      



, .

Decorators in Python




Python:

def my_shiny_new_decorator(function_to_decorate):

    def the_wrapper_around_the_original_function():

        print(" - ,     ")

        function_to_decorate()

        print("  - ,  ")

    return the_wrapper_around_the_original_function
      
      



my_shiny_new_decorator(). function_to_decorate() . the_wrapper_around_the_original_function - , . :

print(" - ,     ")

print("  - ,  ")
      
      



My_shiny_new_decorator() the_wrapper_around_the_original_function().

To work out any function, it turns into a decorator.

stand_alone_function = my_shiny_new_decorator(stand_alone_function)
      
      



In this case, the decorated function is stand_alone_function, the decorator is my_shiny_new_decorator. The value is assigned to the stand_alone_function variable.

def stand_alone_function():

    print("   ,      ?")

stand_alone_function()
      
      



 - ,     

   ,      ?

  - ,  
      
      



Thus, it can be seen that stand_alone_function, which displayed one sentence, now displays three sentences. This is done using a decorator.




All Articles