python advanced syntax -- closures, decorators

1. Property property

1.1 definition

The property attribute is responsible for using a method in the class as a property, which can simplify the code

1.2 decorator mode

class Person(object):
    def __init__(self):
        self.__age =0
        
    @property
    def age(self):
        return self.__age
    @age.setter
    def age(self,new_age):
        self.__age = new_age

p=Person()
print(p.age)
p.age=100
print(p.age)

1.3 class attribute method

Parameter of property

The first parameter is to get the property, which is the method to execute

The second parameter is the method to execute when setting the property

There are two ways to define the property attribute: 1. Decorator mode; 2. Class attribute mode

Decorator mode: 1. property modifies the method of obtaining value

2, @ method name. setter modifies the method of setting a value

Class attribute mode

1. Property property = property (get value method, set value method)

class Person(object):
    def __init__(self):
        self.__age = 0

    def get_age(self):
        return self.__age

    def set_age(self,new_age):
        if new_age>=150:
            print("Age error")
        else:
            self.__age=new_age
    age = property(get_age,set_age)

p=Person()
print(p.age)
# set a property
p.age=100
print(p.age)

2. with statement

python provides the with statement to simplify the operation of resource release. The operation using the with statement is based on the context manager (implementing the enter and exit methods)

class File(object):
    def __init__(self,file_name,file_model):
        self.file_name = file_name
        self.file_name= file_model
    def __enter__(self):
        print("This is the above")
        self.file = open(self.file_name,self.file_model)
        return self.file
    def __exit__(self, exc_type, exc_val, exc_tb):
        print("This is the following")
        self.file.close()

with File("1.txt","r") as f:
    file_data=f.read()
    print(file_data)

3. Generator

3.1 function

Generate data circularly according to the rules specified by the programmer. When the conditions are not tenable, the generated data ends.

Instead of generating all the data at once, use one and regenerate it into one, which can save a lot of memory

3.2 generator derivation

It is similar to the list derivation, except that the generator derivation uses parentheses

data = (x for x in range(100))
next(data)

for i in data:
    print(i)

Generator related functions

The next function gets the next value in the generator

The for loop iterates through each value in the generator

3.3. yield keyword

Feature of yield keyword generator: it has yield keyword in def function

def mygenerater(n):
    for i in range(n):
        print('Start build....')
        yield
        print('Finish once.....')
g= mygenerater(5)
# print(next(g))
# print(next(g))
# print(next(g))

for i in g:
    print(i)

1. When the code is executed to yield, it will be suspended, and then the result will be returned. The next time the generator is started, it will continue to execute at the suspended position

2. If the generator completes the data generation and obtains the next data in the generator again, it will throw a StopIteration exception to stop the iteration

3. There are no exception handling operations inside the while loop. You need to add exception handling operations manually

4. The for loop automatically handles the stop iteration exception, which is more convenient to use. It is recommended

3.4. The generator generates a Fibonacci sequence

(add the first two numbers) 1, 2, 3, 5, 8, 13, 21.....

def fb(num):
    a =0
    b=1
    index =0
    while index< num:
        result = a
        a,b = b,a+b
        yield result
        index +=1
f=fb(8)
for i in f:
    print(i)

1. Generator is a mechanism for generating data according to the algorithm. Only one value is generated each time the generator is called, which can save a lot of memory

2. Creation of generator

4. Deep and shallow copies

The copy function copies only the first layer objects of variable types

Open up new memory space for the copied object for storage, and the object will not be copied

4.1 variable type shallow copy

#Normal assignment
import copy
a =[1,2,3]
b=[11,22,33]
c =[a,b]
d=c
print(id(d))
print(id(c))

#Shallow copy variable type
import copy
a =[1,2,3]
b=[11,22,33]
c =[a,b]
d=copy.copy(c)
print(id(d))
print(id(c))

#Shallow copy, deep data
import copy
a =[1,2,3]
b=[11,22,33]
c =[a,b]
d=copy.copy(c)
print(id(a))
print(id(c[0]))
print(id(d[0]))

#Shallow copy immutable type
import copy
a =[1,2,3]
b=[11,22,33]
c =(a,b)
d=copy.copy(c)
print(id(a))
print(id(c[0]))
print(id(d[0]))

4.2 deep copy

For each layer of copied objects, new memory space will be opened up for storage

# Deep copy, variable data
import copy
a =[1,2,3]
b=[11,22,33]
c =[a,b]
d=copy.deepcopy(c)
# print(id(a))
print(id(c))
print(id(d))

# Deep copy
import copy
a =[1,2,3]
b=[11,22,33]
c =(a,b)
d=copy.deepcopy(c)
print(id(a))
print(id(c[0]))
print(id(d[0]))

#Deep copy immutable type

import copy
a =(1,2,3)
b=(11,22,33)
c =(a,b)
d=copy.deepcopy(c)
print(id(c))
print(id(d))

5. Function parameters

Function: 1. The function name stores the address of the space where the function is located

2. Function name () executes the code in the space address where the function name is stored

3. The following func01=func02 function name can be assigned as an ordinary variable, and func01() is equivalent to func0()

def func01():
    print("func01 is show")

def foo(func):
    func()
foo(func01)

6. Closure

6.1 closure function:

Closures can save variables in a function and will not be destroyed as the function is called

6.2 definition of closure

On the premise of function nesting, the internal function uses the variables of the external function, and the external function returns the internal function. We call the internal function using the external function variables as a closure.

6.3 conditions constituting closure

1. Nesting in functions

2. Internal functions use variables of external functions

3. An external function returned an internal function

6.4 use of closures

def config_name(name):
    def say_info(info):
        print(name + ":" , info)
    return say_info

tom =config_name("tom")
tom("Hello")
tom("Are you there")

jerry = config_name("jerry")
jerry("Hello")
jerry("I'm here")

6.5. Modify closure

Modify the external variables used in the closure using the nonlocal keyword

def func_out(num1):
    def func_inner(num2):
        nonlocal num1
        num1 = num2 + 10

    print(num1)
    func_inner(10)
    print(num1)

    return func_inner

f=func_out(10)
f(10)

7. Decorator

7.1 function of decorator

Add new functions to the function without changing the source code of the original function

The decorator conforms to the closed principle in development

It's essentially a closure

Syntax format of decorator

def check(fn):
    def inner():
        print("Login authentication....")
        fn()
    return inner
#When the interpreter encounters @ check, it will immediately execute comment = check(comment)
@check
def comment():
    print("Comment")

#comment = check(comment)
comment()

7.2 use of decorators

Usage scenario: function execution time statistics

import time
def get_time(fn):
    def inner():
        start = time.time()
        fn()
        end = time.time()
        print("Time:",end-start)
    return inner

@get_time
def func():
    for i in range(10000):
        print(i)

func()

Decorator function: extend the functions of existing functions without changing the source code and calling mode of existing functions

7.3. Universal decorator - function with parameters

def logging(fn):
    def inner(a,b):
        fn(a,b)
    return inner

@logging
def sum_num(a,b):
    result = a + b
    print(result)

sum_num(1,2)

7.4. Decorating functions with return values

def logging(fn):
    def inner(a,b):
        result=fn(a,b)
        return result
    return inner

@logging
def sum_num(a,b):
    result = a + b
    return result
    
result = sum_num(1,2)
print(result)

7.5. Decorating functions with indefinite length parameters

def logging(fn):
    def inner(*args, **kwargs):
        fn(*args, **kwargs )

    return inner

@logging
def sum_num(*args, **kwargs):
    print(args,kwargs)

sum_num(1, 2,3,age=18)

7.6 multiple decorators

def check1(fn1):
    def inner1():
        print("validate logon")
        fn1()
    return inner1
def check2(fn2):
    def inner2():
        print("Login authentication 2")
        fn2()
    return inner2
@check2
@check1
def comment():
    print("Comment")

comment()

The decorator closest to the function is decorated first, and then the external decorator is decorated again. The decoration process is from inside to outside

7.7 decorator with parameters

When decorating a function with a decorator, you can pass in the specified parameters

Syntax: @ decorator (parameter...)

def logging(flag):

    def decorator(fn):
        def inner(num1,num2):
            if flag == "+":
                print("Trying to add")
            elif flag == "-":
                print("Trying to subtract")
            result = fn(num1,num2)
            return result
        return inner
    return decorator

@logging('+')
def add(a,b):
    result = a+b
    return result

result = add(1,3)
print(result)

Decorator with parameters

1. The decorator's external function accepts only one parameter - the decorated function

2. You need to pass parameters to the decorator. You need to add another function outside the decorator

7.8 class I decorators

__ call __ Use of methods

Once implemented in a class__ call __ method

Then the object created by this class is a callable object, which can be called like a function

class Check(object):
    def __init__(self,fn):
        self._fn = fn

    def __call__(self, *args, **kwargs):
        print("I am call method")
        self._fn()

@Check
def comment():
    print("Comment")

comment()

Tags: Python

Posted on Wed, 29 Sep 2021 20:55:57 -0400 by geo3d