python装饰器详述
Posted 仙寓游子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python装饰器详述相关的知识,希望对你有一定的参考价值。
装饰器:
可以解释为函数,装饰器就是装饰函数;
功能:装饰器本身是函数,用来装饰其他函数的。
就是为其他函数添加附加功能。
例1:
def test1():
pass
def test2():
pass
test1()
test2()
此时需要给源码test1和test2添加记录日志功能。
函数表示:
def logger():
print("logging....")
def test1():
pass
logger()
def test2():
pass
logger()
test1()
test2()
这样相当于修改整个源代码(上线源代码原则是不能修改)不符合装饰器要求。
装饰器的原则:
1. 不能修改被装饰的函数的源代码;
2. 不能修改被装饰的函数的调用方式;
实现装饰器知识储备:
1. 函数即"变量"
2. 高阶函数
a. 把一个函数名当作实参传给另外一个函数(在不修改被装饰函数源代码的情况下为其添加新功能);
b. 返回值包含函数名;
可以解释为函数,装饰器就是装饰函数;
功能:装饰器本身是函数,用来装饰其他函数的。
就是为其他函数添加附加功能。
例1:
def test1():
pass
def test2():
pass
test1()
test2()
此时需要给源码test1和test2添加记录日志功能。
函数表示:
def logger():
print("logging....")
def test1():
pass
logger()
def test2():
pass
logger()
test1()
test2()
这样相当于修改整个源代码(上线源代码原则是不能修改)不符合装饰器要求。
装饰器的原则:
1. 不能修改被装饰的函数的源代码;
2. 不能修改被装饰的函数的调用方式;
实现装饰器知识储备:
1. 函数即"变量"
2. 高阶函数
a. 把一个函数名当作实参传给另外一个函数(在不修改被装饰函数源代码的情况下为其添加新功能);
b. 返回值包含函数名;
例2:
def bar():
print("in the bas.......")
def test1(func):
print(func)
func() #加小括号即表示运行;
test1(bar)
输出:
<function bar at 0x03B5BA50> #内存地址
in the bas.......
例3:
import time
def bar(): #源代码
time.sleep(3)
print("in the bas.......")
def test1(func):
start_time = time.time()
func()
stop_time = time.time()
print(" the func run time is %s" %(stop_time - start_time))
#bar() #原调用方式
test1(bar) #改变了调用方式
func() #加小括号即表示运行;
test1(bar)
输出:
<function bar at 0x03B5BA50> #内存地址
in the bas.......
例3:
import time
def bar(): #源代码
time.sleep(3)
print("in the bas.......")
def test1(func):
start_time = time.time()
func()
stop_time = time.time()
print(" the func run time is %s" %(stop_time - start_time))
#bar() #原调用方式
test1(bar) #改变了调用方式
输出:
in the bas.......
the func run time is 3.000096321105957
例4:
import time
def bar():
time.sleep(3)
print("in the bas.......")
def test2(func):
print(func)
return func
print(test2(bar)) #将内存地址作为参数传输
输出:
<function bar at 0x0327BA50> #返回bar内存地址
<function bar at 0x0327BA50>
例5;
import time
def bar():
time.sleep(3)
print("in the bas.......")
def test2(func):
print(func) #类似加了新功能:
return func
bar = test2(bar) #覆盖原来的bar(门牌号)
bar()
输出:
<function bar at 0x0320BA50>
in the bas.......
注意:高阶函数是不能return 自己的
3. 嵌套函数:
在函数体内用def去定义一个函数,叫做函数的嵌套;
嵌套函数1:
def foo():
print("in the foo")
def bar():
print("in the bar")
bar()
foo()
嵌套函数1:
def foo():
print("in the foo")
def bar():
print("in the bar")
bar()
foo()
输出:
"in the foo"
"in the bar"
局部作用域和全局作用域的访问顺序:
x = 0
def grandpa():
x=1
def dad():
x=2
def son():
x = 3
print(x)
son()
dad()
grandpa() #调用;
输出:3
局部作用域和全局作用域的访问顺序:
x = 0
def grandpa():
x=1
def dad():
x=2
def son():
x = 3
print(x)
son()
dad()
grandpa() #调用;
输出:3
高阶函数+嵌套函数 =》装饰器:
import time
#高阶函数
def timer(func):
def deco():
start_time = time.time()
func() #高阶函数
import time
#高阶函数
def timer(func):
def deco():
start_time = time.time()
func() #高阶函数
end_time = time.time()
print(" the func run time is %s" %(end_time - start_time))
return deco #带有返回值的高阶函数
@timer #@timer 等于 test1 = timer(test1)
def test1():
time.sleep(3)
print("in the test1......")
@timer
def test2():
time.sleep(3)
print("in the test2......")
return deco #带有返回值的高阶函数
@timer #@timer 等于 test1 = timer(test1)
def test1():
time.sleep(3)
print("in the test1......")
@timer
def test2():
time.sleep(3)
print("in the test2......")
#test1() #源执行方式
#test2()
#deco(test1)
#deco(test2)
#test1 = timer(test1)
#test2 = timer(test2)
#test1()
#test2()
test1() #执行的deco()
test2()
单参数传输:
import time
def timer(func):
def deco(p1):
start_time = time.time()
func(p1)
end_time = time.time()
print(" the func run time is %s" % (end_time - start_time))
return deco
@timer # test2 = timer(test2)=deco, 所以test()=deco()等于test(p1)=deco(p1)
def test2(name):
time.sleep(1)
print("in the test2 -- %s......"% name)
test2("brace")
输出:
in the test2 -- brace......
the func run time is 1.0179989337921143
多参数或不固定参数:
import time
def timer(func):
def deco(*args, **kwargs):
start_time = time.time()
func(*args,**kwargs)
end_time = time.time()
print(" the func run time is %s" % (end_time - start_time))
return deco
#test2()
#deco(test1)
#deco(test2)
#test1 = timer(test1)
#test2 = timer(test2)
#test1()
#test2()
test1() #执行的deco()
test2()
单参数传输:
import time
def timer(func):
def deco(p1):
start_time = time.time()
func(p1)
end_time = time.time()
print(" the func run time is %s" % (end_time - start_time))
return deco
@timer # test2 = timer(test2)=deco, 所以test()=deco()等于test(p1)=deco(p1)
def test2(name):
time.sleep(1)
print("in the test2 -- %s......"% name)
test2("brace")
输出:
in the test2 -- brace......
the func run time is 1.0179989337921143
多参数或不固定参数:
import time
def timer(func):
def deco(*args, **kwargs):
start_time = time.time()
func(*args,**kwargs)
end_time = time.time()
print(" the func run time is %s" % (end_time - start_time))
return deco
@timer
def test():
time.sleep(1)
print("in the test1......")
@timer
def test2(name,age):
time.sleep(1)
print("in the test2 -- %s......"% name)
print("in the test2 -- %s......"% age)
test1()
test2("brace","12")
输出:
in the test1......
the func run time is 1.0099728107452393
in the test2 -- brace......
in the test2 -- 12......
the func run time is 1.020176649093628
一个页面代表一个函数:
100个页面相当100个函数:
def test():
time.sleep(1)
print("in the test1......")
@timer
def test2(name,age):
time.sleep(1)
print("in the test2 -- %s......"% name)
print("in the test2 -- %s......"% age)
test1()
test2("brace","12")
输出:
in the test1......
the func run time is 1.0099728107452393
in the test2 -- brace......
in the test2 -- 12......
the func run time is 1.020176649093628
一个页面代表一个函数:
100个页面相当100个函数:
无返回值的装饰器:
user = "brace"
passwd = "123"
def auth(func):
def wrapper(*args,**kwargs):
username = input("user name:").strip()
password = input("pass word:").strip()
if user = usernae and passwd = password:
print(" 33[32;1mUser had passed authentication! 33[0m")
func(*args,**kwargs) #相关于执行原函数
else:
exit( 33[31;1minvalid username and password! 33[0m)
return wrapper
def index():
print("welcome to index page.....")
@auth #home = auth(home)=wrapper的内存地址
def home():
print("welcome to index page.....")
@auth
def bbs():
print("welcome to index page.....")
index() #执行的是wrapper()
home()
bbs()
user = "brace"
passwd = "123"
def auth(func):
def wrapper(*args,**kwargs):
username = input("user name:").strip()
password = input("pass word:").strip()
if user = usernae and passwd = password:
print(" 33[32;1mUser had passed authentication! 33[0m")
func(*args,**kwargs) #相关于执行原函数
else:
exit( 33[31;1minvalid username and password! 33[0m)
return wrapper
def index():
print("welcome to index page.....")
@auth #home = auth(home)=wrapper的内存地址
def home():
print("welcome to index page.....")
@auth
def bbs():
print("welcome to index page.....")
index() #执行的是wrapper()
home()
bbs()
带返回值的装饰器:
user = "brace"
passwd = "123"
def auth(func):
def wrapper(*args,**kwargs):
username = input("user name:").strip()
password = input("pass word:").strip()
if user = usernae and passwd = password:
print(" 33[32;1mUser had passed authentication! 33[0m")
res = func(*args,**kwargs)
return res
else:
exit( 33[31;1minvalid username and password! 33[0m)
return wrapper
def index():
print("welcome to index page.....")
@auth
def home():
print("welcome to index page.....")
return "form home"
@auth
def bbs():
print("welcome to index page.....")
index()
home()
bbs()
带参数的装饰器:装饰器带参数:
user = "brace"
passwd = "123"
def auth(func):
def wrapper(*args,**kwargs):
username = input("user name:").strip()
password = input("pass word:").strip()
if user = usernae and passwd = password:
print(" 33[32;1mUser had passed authentication! 33[0m")
res = func(*args,**kwargs)
return res
else:
exit( 33[31;1minvalid username and password! 33[0m)
return wrapper
def index():
print("welcome to index page.....")
@auth
def home():
print("welcome to index page.....")
return "form home"
@auth
def bbs():
print("welcome to index page.....")
index()
home()
bbs()
带参数的装饰器:装饰器带参数:
user,passwd = "brace","1234"
def auth(auth_type):
print("auth type:", auth_type)
def out_wrapper(func):
print("out_wrapper func:",func)
def wrapper(*args, **kwargs):
print("wrapper args:", *args)
print("wrapper kwargs:", **kwargs)
if auth_type == "local":
username = input("user name:").strip()
password = input("pass word:").strip()
if user == username and passwd == password :
print(" 33[32;1mUser had passed authentication! 33[0m")
res = func(*args, **kwargs)
return res
else:
exit(" 33[31;1minvalid username and password! 33[0m")
else:
print("waiting for development......! ")
res = func(*args, **kwargs)
return res
return wrapper
return out_wrapper
def index():
print("welcome to index page.....")
@auth(auth_type="local")
def home(name):
print("welcome to index page.....", name)
return "form home"
@auth(auth_type="ldap")
def bbs():
print("welcome to index page.....")
输出:
auth type: local
out_wrapper func: <function home at 0x02E0BAE0>
auth type: ldap
out_wrapper func: <function bbs at 0x02E0BA50>
welcome to index page.....
wrapper args: brace
wrapper kwargs:
user name:brace
pass word:1234
User had passed authentication!
welcome to index page..... brace
wrapper args:
wrapper kwargs:
waiting for development......!
welcome to index page.....
def auth(auth_type):
print("auth type:", auth_type)
def out_wrapper(func):
print("out_wrapper func:",func)
def wrapper(*args, **kwargs):
print("wrapper args:", *args)
print("wrapper kwargs:", **kwargs)
if auth_type == "local":
username = input("user name:").strip()
password = input("pass word:").strip()
if user == username and passwd == password :
print(" 33[32;1mUser had passed authentication! 33[0m")
res = func(*args, **kwargs)
return res
else:
exit(" 33[31;1minvalid username and password! 33[0m")
else:
print("waiting for development......! ")
res = func(*args, **kwargs)
return res
return wrapper
return out_wrapper
def index():
print("welcome to index page.....")
@auth(auth_type="local")
def home(name):
print("welcome to index page.....", name)
return "form home"
@auth(auth_type="ldap")
def bbs():
print("welcome to index page.....")
输出:
auth type: local
out_wrapper func: <function home at 0x02E0BAE0>
auth type: ldap
out_wrapper func: <function bbs at 0x02E0BA50>
welcome to index page.....
wrapper args: brace
wrapper kwargs:
user name:brace
pass word:1234
User had passed authentication!
welcome to index page..... brace
wrapper args:
wrapper kwargs:
waiting for development......!
welcome to index page.....
以上是关于python装饰器详述的主要内容,如果未能解决你的问题,请参考以下文章