十、装饰器,闭包

一、闭包函数:
1.定义在函数内部的函数
2.内部函数引用了外部函数名称空间作用域的名字
主要满足上面的两点都叫做闭包函数

*****一定要在内部函数一定要有调用外部函数名称才能称为闭包

1.闭包函数
1.闭:定义在函数内部的函数
2.包:内部函数引用了外部函数作用域的名字
# def outter():
#     x = 111
#     def inner():
#         print(x)
#     return inner
# res = outter()  # res就是inner函数内存地址
#
# def func():
#     x = 333
#     res()
# func()
1.inner()函数调用了外部函数outter()x的值。
2.inner()函数在outter()函数里面
这就是闭包

函数在定义阶段名字的查找顺序就已经固定死了
不会因为函数调用位置的变化而改变!!!

小爬虫,
爬虫的本质就是爬取页面的html代码
从中获取到你想要的数据(url链接地址)
有了链接之后 你就可以顺着这个链接将所有的页面资源全部爬取下来

# 第一个直接给函数传参
url1 = 'https://www.baidu.com'
url2 = '...'
def my_get(url):
    response = requests.get(url)
    if response.status_code == 200:
        print(len(response.text))

my_get(url1)
my_get(url1)
my_get(url1)
my_get('https://www.baidu.com')
my_get('https://www.baidu.com')
my_get('https://www.baidu.com')
View Code

二.装饰器的简介

装饰器:
器:就是一个工具
装饰:给被装饰对象添加新的功能
开放封闭原则:
开放:对扩展开放
封闭:对修改封闭

装饰器(可调用对象)必须遵循的两个原则:
1.不改变被装饰对象源代码
2.不改变被装饰对象(可调用对象)调用方式
1.统计index函数执行的时间
"""
import time
def index():
    time.sleep(3)
    print('澳门最大线上赌场开业啦 性感tank在线发牌!')

start = time.time() #计时开始
index()
end = time.time()  # 计时结束
print('index run time:%s'%(end-start))
# 2.如果引用装饰器
import time


def index():
    time.sleep(3)
    print("上海真的好好玩!")


def outter(func):
    def get_time():
        start = time.time()
        func()
        end = time.time()
        print("执行这个函数所花的时间%s"%(start-end))
    return get_time


index = outter(index)  # 把函数当作参数传进去,index=func,res=get_time,
                      #  在不改变函数的情况下,添加功能
index()
# index指向get_time函数的内存地址然后去执行
# 3.有参数的装饰器
# 函数可以接收任意数量的参数
# 需求计算login函数运行时间
import time


def login(name):
    time.sleep(3)
    print(f"{name}是个二货")
    return "login"


# 弄个闭包函数
def outter(func):
    def get_time(*args, **kwargs):
        start = time.time()
        res = func(*args, **kwargs)
        end = time.time()
        print(f"函数运行的时间:{start - end}")
        return res

    return get_time
login = outter(login)
res2=login("鸡哥")
print(res2)
# 在装饰的过程中既把函数login运行时间测试出来,又运行login函数并得到login返回值

三.装饰器语法糖

# 语法糖在书写的时候应该与被装饰对象紧紧挨着 
# 两者之间不要有空格
import time



# 弄个闭包函数
def outter(func):
    def get_time(*args, **kwargs):
        start = time.time()
        res = func(*args, **kwargs)
        end = time.time()
        print(f"函数运行的时间:{start - end}")
        return res

    return get_time
@outter
def login(name):
    time.sleep(3)
    print(f"{name}是个二货")
    return "login"
# 在login函数上面加上@outter,是装饰login函数增添outter函数功能,注意加装饰器一定是先定义后加装
#并且@outter  相当于login = outter(login)的省略,下面 只需要执行login函数就可以了
res = login("坦克")
print(res)

四.装饰器的模板:

# 1.装饰器的模板

def outter(func):
    def inner(*args,**kwargs):
        print("执行前的代码")
        res = func(*args,**kwargs)
        print("执行后的代码")
        return res
    return inner
def index():
    pass

index=outter(index)
res1 =index(*args,**kwargs)
print(res1)
2.多层装饰器模板   
 from functools import wraps
    def outter(func):
        @wraps(func)
        def inner(*args,**kwargs):  # * **在形参中使用
            # 执行被装饰函数之前你可以做的操作
            res = func(*args,**kwargs)  # * **在实参中使用
            # 执行被装饰函数之后你可以做到操作
            return res
        return inner

    @outter
    def index(username,*args,**kwargs):
        """index注释"""
        pass
    print(index)

五.装饰器修复

# 装饰器修复术
from functools import wraps  # 导入模块functools  wraps功能
def outter(func):
    @wraps(func)  # 装饰器修复,返回是原来函数内存地址
    def inner(*args,**kwargs):
        # 执行前的代码
        res = func(*args,**kwargs)
        # 执行后的代码
        return res
    return inner
@outter # index=outter(index)
def index():
    pass
res1=index(*args,**kwargs)
print(res1)
 #返回是原来函数内存地址

六.多层装饰器

 1 def outter1(func1):
 2     print('加载了outter1')
 3 
 4     def wrapper1(*args, **kwargs):
 5         print('执行了wrapper1')
 6         res1 = func1(*args, **kwargs)
 7         return res1
 8 
 9     return wrapper1
10 
11 
12 def outter2(func2):
13     print('加载了outter2')
14 
15     def wrapper2(*args, **kwargs):
16         print('执行了wrapper2')
17         res2 = func2(*args, **kwargs)
18         return res2
19 
20     return wrapper2
21 
22 
23 def outter3(func3):
24     print('加载了outter3')
25 
26     def wrapper3(*args, **kwargs):
27         print('执行了wrapper3')
28         res3 = func3(*args, **kwargs)
29         return res3
30 
31     return wrapper3
32 
33 
34 @outter1  # index = outter1(wapper2)
35 @outter2  # wrapper2 = outter2(wrapper3)
36 @outter3  # wrapper3 = outter3(最原始的index函数内存地址)  
37 # 开始:index=outter(index)
38 def index():
39     print('from index')
40 
41 
42 index()
43 # 装饰器在装饰的时候  顺序从下往上
44 # 装饰器在执行的时候  顺序从上往下
45 """
46 加载了outter3
47 加载了outter2
48 加载了outter1
49 
50 执行了wrapper1
51 执行了wrapper2
52 执行了wrapper3
53 from index
54 """
View Code

 



原文地址:https://www.cnblogs.com/wukai66/p/11177256.html