python學習筆記之裝飾器

2021-10-19 17:19:33 字數 4852 閱讀 6240

def

print_msg()

:# print_msg是外函式

msg =

"i'm 狂師"

defprinter()

:# printer是巢狀函式

print

(msg)

return printer # 返回巢狀函式printer

def

func

(a, b)

:def

line

(n):

nonlocal a # nonlocal用於宣告變數a是外圍函式的變數

a = a +

1return a * n - b

return line

裝飾器的作用是在不改變函式源**並且不改變函式呼叫方式的情況下,增強函式的功能,裝飾器本身也是乙個函式或者類。

寫乙個裝飾器可以為函式新增列印日誌的功能

import logging

logging.basicconfig(

format

='%(asctime)s - %(levelname)s: %(message)s'

, level=logging.debug)

# 這個裝飾器可以修飾任何引數和內嵌函式一致的函式

defuse_logging

(func)

:def()

: logging.info(

"%s is running"

% func.__name__)

func(

)@use_logging

deffun_a()

:print

('i am a'

)@use_logging

deffun_b()

:print

('i am b'

)fun_a(

)fun_b(

)# 裝飾器的第二種使用方式

fun_a = use_logging(fun_a)

fun_a(

)

class

testclass

(object):

def__init__

(self, func)

: self._func = func

def__call__

(self)

:# 類裝飾器必須實現__call__方法

print

('class decorator runing'

) self._func(

)print

('class decorator ending'

)@testclass

deffun_a()

:print

('fun_a is running'

)fun_a(

)

import logging

logging.basicconfig(

format

='%(asctime)s - %(levelname)s: %(message)s'

,level=logging.debug)

defuse_logging

(level)

:# 裝飾器帶引數

defdecorator

(func)

:def

(*args,

**kwargs)

:# 修飾函式的引數要和被修飾函式的引數一致

if level ==

"warn"

: logging.warning(

"%s is running by warning"

% func.__name__)

elif level ==

"info"

: logging.info(

"%s is running by info"

% func.__name__)

return func(

*args,

**kwargs)

return decorator

@use_logging(level=

"warn"

)def

fun_a

(*args,

**kwargs)

:print

("i am %s %s"

%(args,kwargs)

)@use_logging(level=

"info"

)def

fun_b

(*args,

**kwargs)

:print

("i am %s %s"

%(args,kwargs)

)fun_a(18,

20,name=

"張三"

)fun_b(

20,name=

"李四"

,age=

18)

from functools import wraps

# 裝飾器

defuse_print

(func)

: @wraps(func)

defwith_logging

(*args,

**kwargs)

:print

('calling decorated function...'

)return func(

*args,

**kwargs)

return with_logging

# 被裝飾函式

@use_print

deffun_a

(x):

"""does some math"""

print

('fun_a'

)# 如果裝飾器的內嵌函式不使用@wraps()裝飾器,則fun_a的名字和文件字串會是裝飾函式的,如果想列印fun_a自己的名字和文件字串,就要加@wraps()裝飾器

print

(fun_a.__name__, fun_a.__doc__)

用於修飾類的方法,從而把方法當做屬性使用

class

dataset

(object):

def__init__

(self)

: self.__name =

"張三"

self.__age =

18

@property

defname

(self)

:return self.__name

@property

defage

(self)

:return self.__age

# 加了這個裝飾器,使用者就可以設定__age的值了,並且進行一些校驗

@age.setter

defage(self, value):if

notisinstance

(value,

int)

:raise valueerror(

'age must be an integer!'

)if value <

0or value >

100:

raise valueerror(

'age must between 0 ~ 100!'

) self.__age = value

test_object = dataset(

)#使用者進行屬性呼叫的時候,直接呼叫name即可,而不用知道屬性名__name,因此使用者無法更改屬性,從而保護了類的屬性。

# 加了@property後,可以用呼叫屬性的形式來呼叫方法,後面不需要加()。

print

(test_object.name)

print

(test_object.age)

test_object.age =

60

def

decorator_a

(func)

:print

('get in a'

)def

inner_a

(*args,

**kwargs)

:print

('get in inner_a'

)return func(

*args,

**kwargs)

return inner_a

defdecorator_b

(func)

:print

('get in b'

)def

inner_b

(*args,

**kwargs)

:print

('get in inner_b'

)return func(

*args,

**kwargs)

return inner_b

# 會先執行a裝飾器,然後執行b裝飾器

@decorator_b

@decorator_a

deff

(x):

print

('fun a'

)return x *2f(

2)# 輸出結果

get in a

get in b

get in inner_b

get in inner_a

fun a

Python之裝飾器學習筆記

裝飾器本質上是乙個python函式,其返回值也是乙個函式物件 作用 不修改原函式情況下,為已有函式新增新的功能。如插入日誌 效能測試 事務處理 快取 許可權校驗等場景。閉包函式 在函式內部定義乙個內嵌函式,內嵌函式引用了外部函式的變數,此時內嵌函式稱為閉包函式。閉包函式所引用的外部定義的變數被叫做自...

Python之裝飾器筆記

概述 用於管理和增強函式和類行為的 提供一種在函式或類定義中插入自動執行 的機制 特點 更明確的語法 更高的 可維護性 更好的一致性 編寫函式基礎 將函式賦給變數 將函式作為引數傳遞 函式巢狀及跨域訪問 函式定義裝飾器 通用性更好 1 函式定義裝飾器 2 通用性更好34 引數化裝飾器 5def ta...

Python 學習筆記 裝飾器

裝飾器也是乙個函式 巢狀 用來裝飾某個函式,來看下面的 import time deftime count func def start time.time func end time.time print this funnction costs end start deftellhi print...