"""
1.装饰器
什么是装饰器?(what)
可以给被装饰对象增加新功能的工具
装饰器可以是任意可调用类型,被装饰对象也应该是任意可调用对象
装饰器的目标是,用一个函数来给另外一个函数增添新功能
为什么要用装饰器?(why)
开放封闭原则:一个软件上线,应对修改封闭,对扩展开放
原则一:对修改封闭。
1.对被装饰对象的源代码修改封闭
2.对被装饰对象的调用方式封闭
原则二:在满足原则一时对原代码增添新功能。
怎么用装饰器?(how)
"""
# 2.装饰器的修正
# # eg.1
# import time
# def index():
# print('welcome to index page')
# time.sleep(2)###定义了index在在打印以后睡2s
#
# #要实现index()函数执行所花的时间
# def out(func):#将func=index转化成一个传参的形式
# # func=index 这样就是将wapper()做成一个闭包函数
# def wapper():#引入一个参数func=index
# start=time.time()
# func()###所以这个index也可以换成func
# stop=time.time()
# print('run to index() time is %s'%(stop-start))
# return wapper
# ###调用这个函数时,则会算出index()函数执行所花time
# #this have the problem is 调用的是wa'p
# index=out(index)#将index当作参数传到out函数并赋值给index这个变量名
# index()#对取到的函数内存地址经行引用取值
#
# # eg.2
# import time
#
# def index():
# print('welcome to index page')
# time.sleep(2)
# return 123##将return作为返回值打印出来
#
# def outer(func):#func=index的内存地址
# # func()=index()
# def wapper():
# start=time.time()
# res=func()
# stop=time.time()
# print('run index time is %s'%(stop-start))
# return res
# return wapper
# ####返回的是wapper函数的内存地址,给outer
# index=outer(index)#index= outer最原始的index的地址 ,index(新的)=wapper函数的内存地址
#
# #outer(index的内存地址)
# res=index()
# print(res)
# #
# eg.3
import time
# def index():
# print('welcome to index page')
# time.sleep(2)
# return 123
#
# def home(name):
# print('welcome %s to home page'%name)
# time.sleep(1)####相当于有两个对象需要被装饰器装饰
#
# def outer(func):
# def wapper(name):
# start=time.time()
# res=func(name)
# stop=time.time()
# print("run time is %s" %(stop-start))
# return res
# return wapper
#
# home=outer(home)
# home('egon')##新的变量名,类似与index(新)
###如果被修饰对象有参数的话,可以这样写,但是这样写
# eg.4
#需求,要同时可以修饰被修饰对象有参数和没有参数的两种情况
# import time
# def index():
# print('welcome to index page')
# time.sleep(2)
# return 123
#
# def home(name):
# print('welcome %s to home page'%name)
# time.sleep(1)####相当于有两个对象需要被装饰器装饰
#
# def outer(func):
# def wapper(*args,**kwargs):##(*args,**kwargs)是形参的一种格式,无论实参输入的是什么(或者不输入),形参都可以接受
# start=time.time()
# res=func(*args,**kwargs)
# stop=time.time()
# print("run time is %s" %(stop-start))
# return res
# return wapper
#
# home=outer(home)
# home('egon')
# 3.装饰器的语法糖
# 装饰器
# @装饰器的名称
# 被装饰的对象
# import time
# def outer(func):
# def wapper(*args,**kwargs):##(*args,**kwargs)是形参的一种格式,无论实参输入的是什么(或者不输入),形参都可以接受
# start=time.time()
# res=func(*args,**kwargs)
# stop=time.time()
# print("run time is %s" %(stop-start))
# return res
# return wapper
#
# @outer###相当于index=outer(index)
# def index():
# print('welcome to index page')
# time.sleep(2)
# return 123
# index()#####调用index()就好了,注意此处的index是新的,index=wapper
#
# @outer
# def home(name):
# print('welcome %s to home page'%name)
# time.sleep(1)####相当于有两个对象需要被装饰器装饰
# home('egon')
# 这种方式就叫函数的语法糖
# 但是在查看函数的注释中,我们后面调用的新index()=wapper()的,所以查看加了装饰器的index()时,它的注释和
# wapper()是一样的,所以应该吧wapper的注释改成原始的index()的注释一样
# import time
# def outer(func):
# def wapper(*args,**kwargs):##(*args,**kwargs)是形参的一种格式,无论实参输入的是什么(或者不输入),形参都可以接受
# wapper.__doc__=func.__doc__###
# start=time.time()
# res=func(*args,**kwargs)
# stop=time.time()
# print("run time is %s" %(stop-start))
# return res
# return wapper
# @outer###相当于index=outer(index)
# def index():
# """这是index的功能"""
# print('welcome to index page')
# time.sleep(2)
# return 123
# index()
# 修改注释的方式二:
# from functools import wraps###python自带的一个功能
# import time
# def outer(func):
# @wraps(func)#直接将func的注释传给wraps
# def wapper(*args,**kwargs):##(*args,**kwargs)是形参的一种格式,无论实参输入的是什么(或者不输入),形参都可以接受
# wapper.__doc__=func.__doc__###
# start=time.time()
# res=func(*args,**kwargs)
# stop=time.time()
# print("run time is %s" %(stop-start))
# return res
# return wapper
# @outer###相当于index=outer(index)
# def index():
# """这是index的功能"""
# print('welcome to index page')
# time.sleep(2)
# return 123
# index()
# 认证功能小练习
# from functools import wraps###python自带的一个功能
# import time
#
# def outer(func):
# @wraps(func)#直接将func的注释传给wraps
# def wapper(*args,**kwargs):##(*args,**kwargs)是形参的一种格式,无论实参输入的是什么(或者不输入),形参都可以接受
# wapper.__doc__=func.__doc__###
# start=time.time()
# res=func(*args,**kwargs)
# stop=time.time()
# print("run time is %s" %(stop-start))
# return res
# return wapper
#
# def auth(func):
# def wapper(*args,**kwargs):
# name=input('please input your name: ').strip()
# pwd=input('please input your password: ').strip()
# if name== 'egon'and pwd=='123':
# print('login success')
# res=func(*args,**kwargs)
# return res
# return wapper
#
# @outer
# @auth
# def index():
# """这是index的功能"""
# print('welcome to index page')
# time.sleep(2)
# return 123
# index()
# 4.有参装饰器
# 之前学的无参装饰器是@outer后没没有参数
# 有参装饰器就是在@outer(参数)
# def outer2(xxx,yyy):
# def outer(func):
# def wapper(*args,**kwargs):
# res=func(*args,**kwargs)
# print(xxx)
# print(yyy)
# return res
# return wapper()
# return outer
# # 这个就是有参函数的模板
# 5.globals()&nonlocal
#
# x=1
# def outer():
# x=2
# outer()
# print(x)###还是1,说明局部的x=2没能修改成功
x=1
def outer():
global x
x=2
outer()
print(x)###这里是x=2,说明修改成功
# global:是声明这个变量是全局变量
x=333
def f1():
x=222
def f2():
x=111
def f3():
nonlocal x
x=0
f3()
print('f2内部的x: ',x)
f2()
print('这是f1内部的x: ',x)
f1()
print(x)
# nonlocal:是将当前层外层的变量进行修改,只作用一次