導航:首頁 > 編程語言 > python裝飾器定義類

python裝飾器定義類

發布時間:2022-04-19 23:22:59

『壹』 python 類 類方法是否定義前加裝飾器

這個方法如果加了@classmethod那麼第一個參數就是類對象,方法是類方法;如果沒加那麼第一個參數就是實例對象,方法是實例方法。

『貳』 python裝飾器具體是怎麼工作的

分析線面的代碼可以得出結論,可以復制代碼後自行打斷點進行調試
def task(weight=1): # 代碼被執行的時候首先會到這里,執行裝飾器
def decorator_func(func):
func.locust_task_weight = weight return func return decorator_func # 代碼執行的這里的時候會返回來源函數,獲取到來源函數的對象共裝飾器使用@task(1)def test():
print(test)if __name__ == '__main__':
test()

『叄』 python類里的方法怎麼加裝飾器

而Python使用了一種相對於Decorator Pattern和Annotation來說非常優雅的方法,這種方法不需要你去掌握什麼復雜的OO模型或是Annotation的各種類庫規定,完全就是語言層面的玩法:一種函數式編程的技巧。如果你看過本站的《函數式編程》,你一定會為函數式編程的那種「描述你想干什麼,而不是描述你要怎麼去實現」的編程方式感到暢快。(如果你不了解函數式編程,那在讀本文之前,還請你移步去看看《函數式編程》) 好了,我們先來點感性認識,看一個Python修飾器的Hello World的代碼。

『肆』 python裝飾器有什麼用

先來個形象比方

內褲可以用來遮羞,但是到了冬天它沒法為我們防風禦寒,聰明的人們發明了長褲,有了長褲後寶寶再也不冷了,裝飾器就像我們這里說的長褲,在不影響內褲作用的前提下,給我們的身子提供了保暖的功效。

再回到我們的主題

裝飾器本質上是一個Python函數,它可以讓其他函數在不需要做任何代碼變動的前提下增加額外功能,裝飾器的返回值也是一個函數對象。它經常用於有切面需求的場景,比如:插入日誌、性能測試、事務處理、緩存、許可權校驗等場景。裝飾器是解決這類問題的絕佳設計,有了裝飾器,我們就可以抽離出大量與函數功能本身無關的雷同代碼並繼續重用。概括的講,裝飾器的作用就是為已經存在的對象添加額外的功能。

先來看一個簡單例子:

def foo():
print('i am foo')

現在有一個新的需求,希望可以記錄下函數的執行日誌,於是在代碼中添加日誌代碼:

def foo():
print('i am foo')
logging.info("foo is running")

bar()、bar2()也有類似的需求,怎麼做?再寫一個logging在bar函數里?這樣就造成大量雷同的代碼,為了減少重復寫代碼,我們可以這樣做,重新定義一個函數:專門處理日誌 ,日誌處理完之後再執行真正的業務代碼

def use_logging(func):
logging.warn("%s is running" % func.__name__)
func()def bar():
print('i am bar')use_logging(bar)

邏輯上不難理解,
但是這樣的話,我們每次都要將一個函數作為參數傳遞給use_logging函數。而且這種方式已經破壞了原有的代碼邏輯結構,之前執行業務邏輯時,執行運行bar(),但是現在不得不改成use_logging(bar)。那麼有沒有更好的方式的呢?當然有,答案就是裝飾器。


簡單裝飾器
def use_logging(func):

def wrapper(*args, **kwargs):
logging.warn("%s is running" % func.__name__)
return func(*args, **kwargs)
return wrapperdef bar():
print('i am bar')bar = use_logging(bar)bar()

函數use_logging就是裝飾器,它把執行真正業務方法的func包裹在函數裡面,看起來像bar被use_logging裝飾了。在這個例子中,函數進入和退出時
,被稱為一個橫切面(Aspect),這種編程方式被稱為面向切面的編程(Aspect-Oriented Programming)。

@符號是裝飾器的語法糖,在定義函數的時候使用,避免再一次賦值操作


def use_logging(func):

def wrapper(*args, **kwargs):
logging.warn("%s is running" % func.__name__)
return func(*args)
return wrapper@use_loggingdef foo():
print("i am foo")@use_loggingdef bar():
print("i am bar")bar()

如上所示,這樣我們就可以省去bar =
use_logging(bar)這一句了,直接調用bar()即可得到想要的結果。如果我們有其他的類似函數,我們可以繼續調用裝飾器來修飾函數,而不用重復修改函數或者增加新的封裝。這樣,我們就提高了程序的可重復利用性,並增加了程序的可讀性。

裝飾器在Python使用如此方便都要歸因於Python的函數能像普通的對象一樣能作為參數傳遞給其他函數,可以被賦值給其他變數,可以作為返回值,可以被定義在另外一個函數內。


帶參數的裝飾器

裝飾器還有更大的靈活性,例如帶參數的裝飾器:在上面的裝飾器調用中,比如@use_logging,該裝飾器唯一的參數就是執行業務的函數。裝飾器的語法允許我們在調用時,提供其它參數,比如@decorator(a)。這樣,就為裝飾器的編寫和使用提供了更大的靈活性。

def use_logging(level):
def decorator(func):
def wrapper(*args, **kwargs):
if level == "warn":
logging.warn("%s is running" % func.__name__)
return func(*args)
return wrapper

return decorator@use_logging(level="warn")def foo(name='foo'):
print("i am %s" % name)foo()

上面的use_logging是允許帶參數的裝飾器。它實際上是對原有裝飾器的一個函數封裝,並返回一個裝飾器。我們可以將它理解為一個含有參數的閉包。當我
們使用@use_logging(level="warn")調用的時候,Python能夠發現這一層的封裝,並把參數傳遞到裝飾器的環境中。


類裝飾器

再來看看類裝飾器,相比函數裝飾器,類裝飾器具有靈活度大、高內聚、封裝性等優點。使用類裝飾器還可以依靠類內部的\_\_call\_\_方法,當使用 @ 形式將裝飾器附加到函數上時,就會調用此方法。


class Foo(object):
def __init__(self, func):
self._func = func

def __call__(self):
print ('class decorator runing')
self._func()
print ('class decorator ending')

@Foo
def bar():
print ('bar')

bar()

functools.wraps

使用裝飾器極大地復用了代碼,但是他有一個缺點就是原函數的元信息不見了,比如函數的docstring、__name__、參數列表,先看例子:

裝飾器

def logged(func):
def with_logging(*args, **kwargs):
print func.__name__ + " was called"
return func(*args, **kwargs)
return with_logging

函數

@loggeddef f(x):
"""does some math"""
return x + x * x

該函數完成等價於:


def f(x):
"""does some math"""
return x + x * xf = logged(f)

不難發現,函數f被with_logging取代了,當然它的docstring,__name__就是變成了with_logging函數的信息了。

print f.__name__ # prints 'with_logging'print f.__doc__ # prints None

這個問題就比較嚴重的,好在我們有functools.wraps,wraps本身也是一個裝飾器,它能把原函數的元信息拷貝到裝飾器函數中,這使得裝飾器函數也有和原函數一樣的元信息了。

from functools import wrapsdef logged(func):
@wraps(func)
def with_logging(*args, **kwargs):
print func.__name__ + " was called"
return func(*args, **kwargs)
return with_logging@loggeddef f(x):
"""does some math"""
return x + x * xprint f.__name__ # prints 'f'print f.__doc__ # prints 'does some math'

內置裝飾器

@staticmathod、@classmethod、@property

裝飾器的順序
@a@b@cdef f ():

等效於


f = a(b(c(f)))

『伍』 python裝飾器的作用和功能

裝飾器本質上是一個Python函數,它可以讓其他函數在不需要做任何代碼變動的前提下增加額外功能,裝飾器的返回值也是一個函數對象。它經常用於有切面需求的場景,比如:插入日誌、性能測試、事務處理、緩存、許可權校驗等場景。裝飾器是解決這類問題的絕佳設計,有了裝飾器,我們就可以抽離出大量與函數功能本身無關的雷同代碼並繼續重用。概括的講,裝飾器的作用就是為已經存在的對象添加額外的功能

『陸』 如何用python的裝飾器定義一個像C++一樣的強

Python作為一個動態的腳本語言,其函數在定義時是不需要指出參數的類型,也不需要指出函數是否有返回值。使用python的裝飾器來定義一個像C++那樣的強類型函數。接下去,先介紹python3中關於函數的定義。

『柒』 PYTHON里的裝飾器能裝飾類嗎

可以的啦

#-*-coding:UTF-8-*-
fromfunctoolsimportwraps

__author__='lpe234'


defsingleton(cls):
"""
裝飾器實現單例模式
:paramcls:
:return:
"""
instances={}

@wraps(cls)
def_singleton(*args,**kwargs):
ifclsnotininstances:
instances[cls]=cls(*args,**kwargs)
returninstances[cls]
return_singleton


@singleton
classSelfClass(object):
pass


defmain():
s1=SelfClass()
s2=SelfClass()
asserts1iss2

if__name__=='__main__':
main()

『捌』 python裝飾器是什麼意思

裝飾器是程序開發中經常會用到的一個功能,用好了裝飾器,開發效率如虎添翼,所以這也是Python面試中必問的問題,但對於好多小白來講,這個功能 有點繞,自學時直接繞過去了,然後面試問到了就掛了,因為裝飾器是程序開發的基礎知識,這個都 不會,別跟人家說你會Python, 看了下面的文章,保證你學會裝飾器。

1、先明白這段代碼

####第一波####

deffoo():

print'foo'

foo#表示是函數

foo()#表示執行foo函數

####第二波####

deffoo():

print'foo'

foo=lambdax:x+1

foo()#執行下面的lambda表達式,而不再是原來的foo函數,因為函數foo被重新定義了

2、需求來了

初創公司有N個業務部門,1個基礎平台部門,基礎平台負責提供底層的功能,如:資料庫操作、redis調用、監控API等功能。業務部門使用基礎功能時,只需調用基礎平台提供的功能即可。如下:

###############基礎平台提供的功能如下###############

deff1():

print'f1'

deff2():

print'f2'

deff3():

print'f3'

deff4():

print'f4'

###############業務部門A調用基礎平台提供的功能###############

f1()

f2()

f3()

f4()

###############業務部門B調用基礎平台提供的功能###############

f1()

f2()

f3()

f4()

目前公司有條不紊的進行著,但是,以前基礎平台的開發人員在寫代碼時候沒有關注驗證相關的問題,即:基礎平台的提供的功能可以被任何人使用。現在需要對基礎平台的所有功能進行重構,為平台提供的所有功能添加驗證機制,即:執行功能前,先進行驗證。

老大把工作交給 Low B,他是這么做的:

跟每個業務部門交涉,每個業務部門自己寫代碼,調用基礎平台的功能之前先驗證。誒,這樣一來基礎平台就不需要做任何修改了。

當天Low B 被開除了…

老大把工作交給 Low BB,他是這么做的:

###############基礎平台提供的功能如下###############

deff1():

#驗證1

#驗證2

#驗證3

print'f1'

deff2():

#驗證1

#驗證2

#驗證3

print'f2'

deff3():

#驗證1

#驗證2

#驗證3

print'f3'

deff4():

#驗證1

#驗證2

#驗證3

print'f4'

###############業務部門不變###############

###業務部門A調用基礎平台提供的功能###

f1()

f2()

f3()

f4()

###業務部門B調用基礎平台提供的功能###

f1()

f2()

f3()

f4()

過了一周 Low BB 被開除了…

老大把工作交給 Low BBB,他是這么做的:

只對基礎平台的代碼進行重構,其他業務部門無需做任何修改

###############基礎平台提供的功能如下###############

defcheck_login():

#驗證1

#驗證2

#驗證3

pass

deff1():

check_login()

print'f1'

deff2():

check_login()

print'f2'

deff3():

check_login()

print'f3'

deff4():

check_login()

print'f4'

老大看了下Low BBB 的實現,嘴角漏出了一絲的欣慰的笑,語重心長的跟Low BBB聊了個天:

老大說:

寫代碼要遵循開發封閉原則,雖然在這個原則是用的面向對象開發,但是也適用於函數式編程,簡單來說,它規定已經實現的功能代碼不允許被修改,但可以被擴展,即:

『玖』 python修飾器怎樣在類的層次中使用

python在類使用裝飾器有很多方法,下面是其中一個簡單點的:
?

# -*- coding:utf-8 -*-

import inspect
import time

def service_wrap(func):
"""
對service func進行包裝
"""
def wrapped(*args, **kwargs):

print(u' 時間: %s, <%s:%s> [ 參數:<%s %s> ]' %
(time.time(),func.__mole__, func.__name__, args, kwargs))
try:
ret = func(*args, **kwargs)
return ret
except Exception, e:
#TODO
raise e
return wrapped

class BaseService(object):
"""
所有的Service都從該類繼承
"""

def __getattribute__(self, name):
value = object.__getattribute__(self, name)
if inspect.ismethod(value):
if str(name).startswith('__'): #過濾內置方法、屬性
return value
return service_wrap(value)
else:
return value

閱讀全文

與python裝飾器定義類相關的資料

熱點內容
c523壓縮比 瀏覽:543
命令語氣的人什麼心態 瀏覽:435
程序員喜歡留指甲嗎 瀏覽:516
七牛雲伺服器收費標准 瀏覽:627
時光相冊加密空間密碼忘記 瀏覽:474
華為雲為用戶提供的服務雲伺服器 瀏覽:634
minecraftlinux伺服器搭建 瀏覽:376
linux命令新建文件 瀏覽:708
長線pdf 瀏覽:607
程序員電腦支持手寫 瀏覽:414
解壓頭戴式耳機推薦 瀏覽:344
紙條app上怎麼樣看對方主頁 瀏覽:883
編譯英語單詞怎麼寫 瀏覽:249
編譯原理和匯編原理的區別 瀏覽:864
如何給加密的pdf解密 瀏覽:770
華為盒子時間同步伺服器地址 瀏覽:95
python處理excel亂碼 瀏覽:391
mysql的命令行 瀏覽:822
jpeg採用什麼演算法 瀏覽:701
程序員紅軸薄膜 瀏覽:306