python基础---闭包、装饰器
閉包、裝飾器
注意:使用裝飾器,最終都會改變裝飾函數的函數名稱及所屬屬性,所以在實際的裝飾器中如果后續會涉及用到裝飾函數函數名或所屬屬性的,需要加入python自帶的模塊@wraps確保函數裝飾后,不會產生函數名及所屬屬性的改變。示例如下:
# 1 未加入@wraps裝飾器 # coding=utf-8 from functools import wraps def my_decorator(func): def wrapper(*args, **kwargs): '''decorator''' print('Decorated function...') return func(*args, **kwargs) return wrapper @my_decorator def test(): """Testword""" print('Test function') print(test.__name__, test.__doc__)# 打印結果: """ wrapper decorator [Finished in 0.1s] """# 2 加入@wraps裝飾器 from functools import wraps def my_decorator(func): @wraps(func) def wrapper(*args, **kwargs): '''decorator''' print('Decorated function...') return func(*args, **kwargs) return wrapper@my_decorator def test(): """Testword""" print('Test function') print(test.__name__, test.__doc__)# 打印結果: """ test Testword [Finished in 0.1s] """閉包
# 定義:在函數內部再定義一個函數,并且這個函數用到了外邊函數的變量,那么將這個函數以及用到的一些變量稱之為閉包def line_6(k, b):def create_y(x):print(k*x+b)return create_yline_6_1 = line_6(1, 2)line_6_1(0)line_6_1(1)line_6_1(2)line_6_2 = line_6(11, 22)line_6_2(0)line_6_2(1)line_6_2(2)# 思考:函數、匿名函數、閉包、對象 當做實參時 有什么區別?# 1. 匿名函數能夠完成基本的簡單功能,,,傳遞是這個函數的引用 只有功能# 2. 普通函數能夠完成較為復雜的功能,,,傳遞是這個函數的引用 只有功能# 3. 閉包能夠將較為復雜的功能,,,傳遞是這個閉包中的函數以及數據,因此傳遞是功能+數據# 4. 對象能夠完成最為復雜的功能,,,傳遞是很多數據+很多功能,因此傳遞是功能+數據- 裝飾器
不帶參數的裝飾器
@set_func # 等價于test1 = set_func(test1) def test1():print("-----test1----")test1()# 打印結果:"""---這是權限驗證1-------這是權限驗證2---------test1----[Finished in 0.1s]""" ```
```python
def set_func(func):
def call_func():
print("---這是權限驗證1----")
print("---這是權限驗證2----")
func()
return call_func- 帶參數的裝飾器
帶一個參數
@set_func # 相當于 test1 = set_func(test1)def test1(num):print("-----test1----%d" % num)test1(100)# 打印結果:"""---這是權限驗證1-------這是權限驗證2---------test1----100[Finished in 1.3s]"""```
```python
def set_func(func):
def call_func(a):
print("---這是權限驗證1----")
print("---這是權限驗證2----")
func(a)
return call_func帶多個參數
```python
def set_func(func):
print("---開始進行裝飾")
def call_func(*args, **kwargs):
print("---這是權限驗證1----")
print("---這是權限驗證2----")
# func(args, kwargs) # 不行,相當于傳遞了2個參數 :1個元組,1個字典
func(*args, **kwargs) # 拆包
return call_func@set_func # 相當于 test1 = set_func(test1)
def test1(num, *args, **kwargs):
print("-----test1----%d" % num)
print("-----test1----" , args)
print("-----test1----" , kwargs)test1(100)
# 打印結果:
test1(100, 200)
test1(100, 200, 300, mm=100)
"""
---開始進行裝飾
---這是權限驗證1----
---這是權限驗證2----
-----test1----100
-----test1---- ()
-----test1---- {}
---這是權限驗證1----
---這是權限驗證2----
-----test1----100
-----test1---- (200,)
-----test1---- {}
---這是權限驗證1----
---這是權限驗證2----
-----test1----100
-----test1---- (200, 300)
-----test1---- {'mm': 100}
[Finished in 0.2s]
```
通用類的裝飾器
@set_func # 相當于 test1 = set_func(test1)def test1(num, *args, **kwargs):print("-----test1----%d" % num)print("-----test1----" , args)print("-----test1----" , kwargs)return "ok"@set_funcdef test2():passret = test1(100)print(ret)ret = test2()print(ret)# 打印結果:""""""```
```python
# 通用類裝飾器
def set_func(func):
print("---開始進行裝飾")
def call_func(*args, **kwargs):
print("---這是權限驗證1----")
print("---這是權限驗證2----")
# func(args, kwargs) # 不行,相當于傳遞了2個參數 :1個元組,1個字典
return func(*args, **kwargs) # 拆包
return call_func- 對帶有返回值的函數進行裝飾
一個裝飾器裝飾多個函數
@set_func # 相當于 test1 = set_func(test1)def test1(num):print("-----test1----%d" % num)@set_func # 相當于 test2 = set_func(test2)def test2(num):print("-----test2----%d" % num)test1(100)test2(200)# 打印結果:"""---這是權限驗證1-------這是權限驗證2---------test1----100---這是權限驗證1-------這是權限驗證2---------test2----200[Finished in 0.2s] """ ```
```python
def set_func(func):
def call_func(a):
print("---這是權限驗證1----")
print("---這是權限驗證2----")
func(a)
return call_func多個裝飾器裝飾一個函數
def add_xx(func):print("---開始進行裝飾xxx的功能---")def call_func(*args, **kwargs):print("---這是xxx的功能----")return func(*args, **kwargs)return call_func@add_qx@add_xxdef test1():print("------test1------")test1()# 打印結果:"""---開始進行裝飾xxx的功能------開始進行裝飾權限1的功能------這是權限驗證1-------這是xxx的功能----------test1------[Finished in 0.1s] """# 實例:def set_func_1(func):def call_func():# "<h1>haha</h1>"return "<h1>" + func() + "</h1>"return call_funcdef set_func_2(func):def call_func():return "<td>" + func() + "</td>"return call_func@set_func_1@set_func_2def get_str():return "haha"print(get_str())# 打印結果:"""<h1><td>haha</td></h1>[Finished in 0.1s]""" ```
```python
# 多個裝飾器對一個函數進行裝飾:
def add_qx(func):
print("---開始進行裝飾權限1的功能---")
def call_func(*args, **kwargs):
print("---這是權限驗證1----")
return func(*args, **kwargs)
return call_func類裝飾器
def __call__(self):print("這里是裝飾器添加的功能.....")return self.func()@Test # 相當于get_str = Test(get_str)def get_str():return "haha"print(get_str()) # 實際會調用__call__方法# 打印結果:"""這里是裝飾器添加的功能.....haha[Finished in 0.2s]"""
```python
class Test(object):
def init(self, func):
self.func = func```
轉載于:https://www.cnblogs.com/achjiang/p/9908010.html
總結
以上是生活随笔為你收集整理的python基础---闭包、装饰器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JAVA构造MAP并初始化MAP
- 下一篇: 1102面向对象和类原型