1、前言
函數也是一個對象,從而可以增加屬性,使用句點來表示屬性。
如果內部函數的定義包含了在外部函數中定義的對象的引用(外部對象可以是在外部函數之外),那么內部函數被稱之為閉包。
2、裝飾器
裝飾器就是包裝原來的函數,從而在不需要修改原來代碼的基礎之上,可以做更多的事情。
裝飾器語法如下:
@deco2 @deco1 def func(arg1,arg2...): pass
這個表示了有兩個裝飾器的函數,那么表示的含義為:func = deco2(deco1(func))
無參裝飾器語法如下:
@deco def func(): pass
表示的含義為func = deco(func)
有參裝飾器語法如下:
@deco(deco_args) def func(): pass
表示的含義為:func = deco(deco_args)(func)
多個裝飾器有的有參數有的沒參數,語法如下:
@deco2(arg1,arg2) @deco1 def func(): pass
表示的含義為foo = deco2(arg1,arg2)deco1(func)
裝飾器實際上就是函數,接受的也是函數對象。
在執行函數之前,可以運行預備代碼,也可以在執行代碼后做一些清理工作。
看見裝飾器的時候,很可能在里面找到一些代碼,它定義了某個函數,并在定義內的某處嵌入了對目標函數的調用或者至少一點引用。
3、裝飾器作用
裝飾器的作用如下:
引入日志;增加計時邏輯來檢測性能;給函數加入了事物的能力
以下例子表示為引入了計時的邏輯來檢測性能,如下:
#!/usr/bin/env python from time import ctime,sleep def tsfunc(func): #裝飾器函數接受的是一個函數對象 def wrappedFunc(): print '[%s] %s() called' % (ctime(),func.__name__) return func() #在這里調用了函數對象,也就是表示裝飾器是裝飾了原來的函數,從而在原來函數的基礎上進行了一些操作 return wrappedFunc @tsfunc #裝飾器 def foo(): pass foo() sleep(4) for i in range(2): sleep(1) foo()
? 執行結果如下:
[root@python 420]# python deco.py [Tue Apr 19 16:15:01 2016] foo() called [Tue Apr 19 16:15:06 2016] foo() called [Tue Apr 19 16:15:07 2016] foo() called
在裝飾器函數中,增加了時間戳并且調用了目標函數, 裝飾器的返回值是一個包裝了函數 。
4、閉包
如果在一個內部函數里,對在外部作用于(但不是全局作用域)的變量進行引用,那么內部函數被認為是閉包closure,定義在外部函數內的但由內部函數引用或者使用的變量稱之為自由變量。
閉包的主要作用如下:
安裝計算;隱藏狀態;在函數對象和作用域中隨意的切換。
回調就是函數,閉包也是函數,但是能攜帶一點額外的作用域。
#!/usr/bin/env python def counter(start_at=0): count = [start_at] def incr(): count[0] += 1 return count[0] return incr count= counter(5) print count() print count()
在上面的例子可以看到,函數內部的函數incr引用了外部的變量count,并且每次進行加一,從而這個變量count稱之為自由變量。
以上這篇python中函數總結之裝飾器閉包詳解就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
