1. 程式人生 > 其它 >python:語法糖和裝飾器

python:語法糖和裝飾器

python的語法糖就是對指定的目標函式進行裝飾。

要想先了解裝飾器,就必須先知道閉包

python函式的閉包實際上就是一個函式,其傳入的引數是一個函式,返回的仍然是一個函式

例如:

import time
def after_add(func):
def add_thing():
print('----裝飾前------')
func()
print('----裝飾後------')
return add_thing
def add_1():
print((time.strftime('%H:%M:%S',time.localtime(time.time()))))

if __name__== '__main__':
add_2 = after_add(add_1)
add_2()

這裡after_add就形成了一個閉包

那如何形成一個裝飾器?裝飾器其實跟閉包相似,只是裝飾器沒有將新函式傳給一個變數,然後再調入,而是一氣呵成

裝飾器相當於add_2 = after_add(add_1)

所以程式碼可以等價於

import time
def after_add(func):
def add_thing():
print('----裝飾前------')
func()
print('----裝飾後------')
return add_thing
@after_add
def add_1():
print((time.strftime('%H:%M:%S',time.localtime(time.time()))))

if __name__== '__main__':
add_1()

這裡就跟前面的閉包一樣,就跟add_2 =after_add(add_1)這樣分析,先進入after_add(),先定義了函式,然後再得到新函式,接著再呼叫得到的函式,所以最後才打印這個結果

如果像這樣

import time
def after_add(func):
print(11)
def add_thing():
print('----裝飾前------')
func()
print('----裝飾後------')
return add_thing
@after_add
def add_1():
print((time.strftime('%H:%M:%S',time.localtime(time.time()))))

if __name__== '__main__':
add_1()

加入print(11),所以先列印了11

記住兩個原則:

1、裝飾器在函式呼叫之前被增強

2、相同的函式只被增強一次

下面看一下帶引數的裝飾器

目標函式的引數供自己使用,就例如

import time
def say_thing(func):
def say_say(name):
print("Hello")
func(name)
return say_say

@say_thing
def say_name(name):
print(name)
say_name('Li Ming')

這裡注意say_say這裡也需要帶引數,因為裝飾器最後呼叫的是增強後的say_say,需要通過增強函式將引數傳給目標函式.

這裡還注意一點就是如果有多個裝飾器,它是從內往外增強的