python decorator記錄

裝飾器decorator

裝飾器,在設計模式中有一種模式叫做裝飾器模式,雖說不完全是設計模式中的那個,
但是其思路是一致的。目的都是需要添加功能,但是又不希望更改原來的代碼。

比如我已經有一個函數do_something(),然後我希望添加一些功能,但是又不應該
直接去更改這個函數的代碼,我們就可以通過裝飾器的方式,在前後進行添加,並且
將這個函數包裹起來。由於python的函數式特性,我們可以很輕鬆的做到這一點,
因爲其函數是first class的,也就是說函數可以作爲參數等傳遞。

其實這個概念是非常簡單的,如果說有一些麻煩的地方就是python的裝飾器語法,裝飾器
語法其實只是一個語法糖,不過因爲這個語法糖使得裝飾器不那麼直觀了(但是要是沒有
裝飾器語法,我們也就不需要把裝飾器拿出來說啦)

函數作爲參數

在python中,函數可以作爲參數進行傳遞:

def call_a_func(func):
    func()

def hello():
    print("hello")

call_a_func(hello)

這裏我們將hello傳入了call_a_func函數,這個函數將傳入的參數進行調用,也就是其
接收的參數是一個函數,而他調用了這個函數,相信這個例子足以讓人理解函數作爲參數了。

裝飾器語法

裝飾器語法,形式爲:

@decorator
def hello():
    pass

這裏的decorator是裝飾器的名字,也就是另外一個函數,hello是一個函數。

注意,這裏的@decorator 相當於 hello = decorator(hello)

其實這句話纔是我寫這個博客的重點,因爲只要記住這個用法,別的講解都不需要了。

裝飾器,相當於將原函數作爲參數,然後將裝飾器的返回結果代替原函數,有了這個結果,
我們其實就可以隨心所欲使用裝飾器了。

在實際使用當中,有一些技巧,比如:

def deco(func):
    def _deco():
        print("pre")
        func()
        print("post")
    return _deco

@deco
def hello():
    pass

這裏我們相當於使用了hello = deco(hello),最後使得新的hello爲deco內部定義的_deco函數,
這個函數調用了原hello並且在前後增加了功能,爲什麼不直接在前後做一些功能然後返回原來
的hello呢?這是因爲這樣的效果只完成一次,如果返回原hello,只在第一次調用deco的時候
會有前後添加功能的效果,等到deco返回之後,以後的調用就只使用了hello了。所以,裝飾器
並非每一次調用都會進入hello = deco(hello),而是隻進行一次

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章