1.闭包函数:把闭包函数内部的变量和函数包起来,返回闭包函数内部的函数。闭包函数也是一个函数。
def f1():
    def f2():
        print('from f2')
    return f2
res=f1()
res()   #from f2
def f1(url):
    def f2():
        print(url)
    return f2
res=f1('www.taobao.com')
res()  #www.taobao.com
两种为函数传参的方式:
a.使用参数的形式
def f1(x):
    print(x)
f1(1) #1
b.包给函数
def outter(x):
    x=1
    def inner():
        print(x)
    return inner
f=outter(1)
f() #1
2.装饰器:为被装饰器对象添加额外功能,定义装饰器就是定义一个函数,只不过该函数的功能是用来为其他函数添加额外功能。
装饰器的实现必须遵守的两大原则:
a.不修改被装饰对象的源代码
b.不修改被装饰对象的调用方式
3.装饰器的使用
改变源代码
import time
def index():
    '''被装饰的函数'''
    start=time.time()
    print('welcome to index')
    time.sleep(1)
    end=time.time()
    print(f'运行时间是:{end-start}')
index()
运行结果:
welcome to index
运行时间是:1.0000569820404053
编写重复代码:
import time
def index():
    print('index')
    time.sleep(1)
def f1():
    print('f1')
    time.sleep(1)
start=time.time()
index()
end=time.time()
print(end-start)
start=time.time()
f1()
end=time.time()
print(end-start)
运行结果:
index
1.0000574588775635
f1
1.0000569820404053
第一种传参方式:改变调用方式
import time
def index():
    print('index')
    time.sleep(1)
def time_count(func):
    start = time.time()
    func()
    end=time.time()
    print(end-start)
time_count(index) 
运行结果:
index
1.0000572204589844
第二种传参方式:包给函数-外包
import time
def index():
    print('index')
    time.sleep(1)
def time_count(func):   #func是真正的index
    def wrapper():
        start = time.time()
        res=func()
        end=time.time()
        print(end-start)
    return wrapper
res=time_count(index)  #res==wrapper
res()
运行结果:
index
1.0010573863983154
4.完善装饰器:
wrapper 的返回值和index的返回值相同
import time
def index():
    print('index')
    time.sleep(1)
    return 123
def time_count(func):   #func是真正的index
    def wrapper():
        start = time.time()
        func()
        end=time.time()
        print(end-start)
        return res    
    return wrapper
f1=time_count(index)  #res==wrapper
res=f1()
print(res)
运行结果:
index
1.0010573863983154
123
给index传参的实现:
import time
def index():
    print('index')
    time.sleep(1)
def home(name):
    print(f'welcome {name} to home page')
    time.sleep(1)
    return name
def time_count(func):   #func是真正的index
    def wrapper(*args,**kwargs):
        start = time.time()
        res=func(*args,**kwargs)
        end=time.time()
        print(end-start)
        return res
    return wrapper
res=time_count(home) #res==wrapper
f1=res('nick')
print(f1)
运行结果:
welcome nick to home page
1.0000569820404053
nick
5.装饰器语法糖:在被装饰函数正上方,并且是单独的一行@装饰器
def time_count(func):   #func是真正的index
    def wrapper(*args,**kwargs):
        start = time.time()
        res=func(*args,**kwargs)
        end=time.time()
        print(end-start)
        return res
    return wrapper
@time_count
def index():
    print('index')
    time.sleep(1)
    return 123
@time_count
def home(name):
    print(f'welcome {name} to home page')
    time.sleep(1)
    return name
# res=time_count(home) #res==wrapper
f1=home('nick')
print(f1)
f2=index()
print(f2)
运行结果:
welcome nick to home page
1.0000572204589844
nick
index
1.0000572204589844
123
6.装饰器模板:
def deco(func):
    def wrapper(*args,**kwargs):
        res=func(*args,**kwargs)
        return res
    return wrapper
7.三层的有参装饰器:
usename_list=[]
def sanceng(role):
    def login_deco(func):
        def wrapper(*args,**kwargs):
            usename_inp=input('请输入用户名:')
            pwd_inp=input('请输入密码:')
            if usename_list:
                print('已经登录,无须重复')
                res=func(*args,**kwargs)
                return res
            with open(f'{role}_info.txt','r',encoding='utf8') as fr:
                for role_info in fr:
                    usename,pwd=role_info.strip().split(':')
                    if usename==usename_inp and pwd==pwd_inp:
                        print('登录成功')
                        usename_list.append(usename)
                        res = func(*args, **kwargs)
                        return res
                else:
                    print('登录失败')
        return wrapper
    return login_deco
@sanceng('admin')
def index (x,y):
    print('index')
    print('x,y',x,y)
    return 123
res=index(10,30)
运行结果:
请输入用户名:ldd
请输入密码:123
登录成功
index
x,y 10 30
 
                    
                 
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号