網(wǎng)站首頁 編程語言 正文
前言
裝飾器(decorator)在Python框架中扮演著重要角色,是Python中實(shí)現(xiàn)切面編程(AOP)的重要手段。
aspect-oriented programming (AOP) ,在不改變代碼自身的前提下增加程序功能
不改變代碼自身,但需要在函數(shù)和類頭上加一個(gè)標(biāo)注(annotation),這個(gè)標(biāo)注在Python里叫裝飾器,在java里叫注解。
在Python里,一共有四種組合形式。下面一一舉例。
用函數(shù)裝飾函數(shù)
采用一個(gè)函數(shù)定義裝飾器:
def decorate(f):
def wrapper(*args):
return f(*args)*2
return wrapper
然后作用在一個(gè)函數(shù)上:
@decorate
def add(a, b):
return a + b
測試一下效果:
def test_decorate():
sum = add(3, 5)
assert sum == 16
用函數(shù)裝飾一個(gè)類
這里通過裝飾器實(shí)現(xiàn)單例模式:
def singleton(cls):
instances = {}
def wrapper(*args, **kwargs):
if cls not in instances:
instances[cls] = cls(*args, **kwargs)
return instances[cls]
return wrapper
使用該裝飾器:
@singleton
class MyClass:
def method(self):
pass
于是,當(dāng)你定義多個(gè)對(duì)象時(shí),返回的是同一實(shí)例:
obj = MyClass() # creates a new instance
obj2 = MyClass() # returns the same instance
obj3 = MyClass() # returns the same instance
...
用類定義裝飾器,然后裝飾一個(gè)函數(shù)
先采用類定義一個(gè)裝飾器:
class Star:
def __init__(self, n):
self.n = n
def __call__(self, fn):
@wraps(fn)
def wrapper(*args, **kwargs):
result = fn(*args, **kwargs)
return result
return wrapper
再作用在一個(gè)函數(shù)上:
@Star(5)
def add(a, b):
return a + b
主要是在類中實(shí)現(xiàn)__call__方法。上面例子也可以簡化:
class MyDecorator:
def __init__(self, function):
self.function = function
def __call__(self, *args, **kwargs):
# We can add some code
# before function call
self.function(*args, **kwargs)
# We can also add some code
# after function call.
# adding class decorator to the function
@MyDecorator
def function(name, message ='Hello'):
print("{}, {}".format(message, name))
用類定義裝飾器,然后裝飾一個(gè)類
先定義裝飾器:
class MyClassDecorator(object):
_instances = dict()
def __init__(self, name):
pass
def __call__(self, cls):
class WrappedClass(cls):
def say_hello(self):
print(f'Hello: {self.username}')
return WrappedClass
該裝飾器給被裝飾的類上添加了一個(gè)方法,名稱為say_hello()。使用如下:
@MyClassDecorator('test')
class MyClass():
def __init__(self, username):
self.username = username
然后:
def test_decoratorforclass():
obj = MyClass('user1')
obj.say_hello()
打印出: Hello: user1
小結(jié)
學(xué)習(xí)類裝飾,對(duì)Python的內(nèi)部機(jī)制會(huì)有更多的了解。如__init__, call, __new__等內(nèi)置方法。
原文鏈接:https://blog.csdn.net/jgku/article/details/128020535
相關(guān)推薦
- 2022-08-05 Python?如何給圖像分類(圖像識(shí)別模型構(gòu)建)_python
- 2023-08-15 antdv Input組件maxLength屬性設(shè)置默認(rèn)值
- 2022-10-14 el-tree 懶加載,默認(rèn)加載N級(jí).異步加載子節(jié)點(diǎn)
- 2022-05-20 如何保證緩存和數(shù)據(jù)庫的一致性?
- 2022-07-09 Python如何保留float類型小數(shù)點(diǎn)后3位_python
- 2022-05-21 python?判斷文件或文件夾是否存在_python
- 2022-05-22 python?使用tkinter與messagebox寫界面和彈窗_python
- 2023-03-22 一文帶你學(xué)會(huì)Python?Flask框架設(shè)置響應(yīng)頭_python
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支