摘要:所有的描述器協議如下如果一個對象同時定義了和它叫做資料描述器。僅定義了的描述器叫非資料描述器描述器在屬性訪問時被自動調用。
被某些中文教程坑過,我的建議是有問題看官方文檔,即使沒有很詳細的例子,至少不坑
裝飾器毫無疑問在python中用得非常多
def deco(func): def _deco(): print "before invoked" func() print "after invoked" return _deco @deco def f(): print "f is invoked"
在f上加deco裝飾器相當于f = deco(f), 和functools.partial有些類似
如果被裝飾的函數f帶參數且有返回值
def deco(func): def _deco(*args, **kwargs): print "before invoked" ret = func(*args, **kwargs) print "after invoded" return ret return _deco @deco def f(a): print "f is invoked" return a + 1
如果裝飾器帶有參數,需要多包一層,把參數調用包進去
def deco(*args): def _deco(func): def __deco(*args, **kwargs): print "decorator args is", args print "before invoked" ret = func(*args, **kwargs) print "after invoded" return ret return __deco return _deco @deco("test") def f(a): print "f is invoked" return a + 1
只有最里面一層的__deco才會每次都調用,其它外層函數只在包裝時調用一次,當然,你可以在其中聲明變量,然后拿到__deco里使用。如果需要保留函數名,則在__deco上加@functools.wraps裝飾器
使用 類 作裝飾器,注意是類此時相當于裝飾函數,被裝飾的函數會作為實例化參數,得到一個類實例,以python wiki上一個做登錄檢查的代碼為例
class LoginCheck: def __init__(self, f): self._f = f def __call__(self, *args): Status = check_function() if Status is 1: return self._f(*args) else: return alt_function() def check_function(): return test def alt_function(): return "Sorry - this is the forced behaviour" @LoginCheck def display_members_page(): print "This is the members page"描述器
描述器在監視特定屬性的時候很有用,其只在新式類中起作用。所有的描述器協議如下:
descr.__get__(self, obj, type=None) --> value
descr.__set__(self, obj, value) --> None
descr.__delete__(self, obj) --> None
如果一個對象同時定義了 __get__() 和 __set__(),它叫做資料描述器(data descriptor)。僅定義了 __get__() 的描述器叫非資料描述器
描述器在屬性訪問時被自動調用。舉例來說, obj.x 會在 obj 的字典中找x ,如果x定義了 __get__方法,那么 x.__get__(obj)會依據下面的優先規則被調用
調用優先級:
資料描述器 -> 實例字典 -> 非資料描述器
常用的描述器就是property了,一般都只實現了__get__的接口
先給出一個classmethod的實現和一個用于測試描述器優先級的類
class classproperty(object): def __init__(self, func): self.func = func def __get__(self, instance, owner): return self.func(owner) class MyClass(object): @classproperty def name(cls): return cls.__name__ @property def x(self): return self._data @x.setter def x(self, value): self._data = value @x.deleter def x(self): del self._data def __init__(self, val): self._data = val self.x = 3 self.name = "test"
接下來調用
s = MyClass(99) print s.x print s.name print s.__dict__
很明顯x是資料描述器,而name不是,所以結果是
3
5
{"_data": 3, "name": "test"}
如果給classproperty加上__set__,那么就會調用被裝飾的name,而不是實例化時實例字典中的name
一個property的python 實現
class Property(object): "Emulate PyProperty_Type() in Objects/descrobject.c" def __init__(self, fget=None, fset=None, fdel=None, doc=None): self.fget = fget self.fset = fset self.fdel = fdel self.__doc__ = doc def __get__(self, obj, objtype=None): if obj is None: return self if self.fget is None: raise AttributeError, "unreadable attribute" return self.fget(obj) def __set__(self, obj, value): if self.fset is None: raise AttributeError, "can"t set attribute" self.fset(obj, value) def __delete__(self, obj): if self.fdel is None: raise AttributeError, "can"t delete attribute" self.fdel(obj) def getter(self, fget): return type(self)(fget, self.fset, self.fdel, self.__doc__) def setter(self, fset): return type(self)(self.fget, fset, self.fdel, self.__doc__) def deleter(self, fdel): return type(self)(self.fget, self.fset, fdel, self.__doc__)
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/37708.html
摘要:初步認識裝飾器函數裝飾器用于在源代碼中標記函數,以某種方式增強函數的行為。函數裝飾器在導入模塊時立即執行,而被裝飾的函數只在明確調用時運行。只有涉及嵌套函數時才有閉包問題。如果想保留函數原本的屬性,可以使用標準庫中的裝飾器。 《流暢的Python》筆記本篇將從最簡單的裝飾器開始,逐漸深入到閉包的概念,然后實現參數化裝飾器,最后介紹標準庫中常用的裝飾器。 1. 初步認識裝飾器 函數裝飾...
摘要:變量查找規則在中一個變量的查找順序是局部環境,閉包,全局,內建閉包引用了自由變量的函數。閉包的作用閉包的最大特點是可以將父函數的變量與內部函數綁定,并返回綁定變量后的函數,此時即便生成閉包的環境父函數已經釋放,閉包仍然存在。 導語:本文章記錄了本人在學習Python基礎之函數篇的重點知識及個人心得,打算入門Python的朋友們可以來一起學習并交流。 本文重點: 1、掌握裝飾器的本質、功...
摘要:上下文管理器協議包含和兩個方法。因此必要時在上下文管理器函數中使用語句防范錯誤。構建臨時忽略指定異常的上下文管理器。這是個基類,用于定義基于類的上下文管理器。塊結束時,按照后進先出的順序調用棧中各個上下文管理器的方法。 導語:本文章記錄了本人在學習Python基礎之控制流程篇的重點知識及個人心得,打算入門Python的朋友們可以來一起學習并交流。 本文重點: 1、掌握if語句之外的el...
摘要:所以這是一篇插隊的文章,用于去理解中的裝飾器和概念。因此,該的作用就是根據入參返回具體的描述符。其次局部來看,裝飾器具體應用表達式是,其函數簽名和是一模一樣。等裝飾器語法,是和直接使用是等效等價的。 ================前言=================== 初衷:以系列故事的方式展現 MobX 源碼邏輯,盡可能以易懂的方式講解源碼; 本系列文章: 《【用故事解...
摘要:在學習的時候,三大名器對沒有其他語言編程經驗的人來說,應該算是一個小難點,本次博客就博主自己對裝飾器迭代器和生成器理解進行解釋。 在學習python的時候,三大名器對沒有其他語言編程經驗的人來說,應該算是一個小難點,本次博客就博主自己對裝飾器、迭代器和生成器理解進行解釋。 裝飾器 什么是裝飾器?裝飾從字面意思來誰就是對特定的建筑物內按照一定的思路和風格進行美化的一種行為,所謂器就是工具...
閱讀 1624·2021-11-22 14:45
閱讀 1075·2021-11-17 09:33
閱讀 3328·2021-09-02 09:48
閱讀 975·2019-08-30 15:54
閱讀 2771·2019-08-30 15:53
閱讀 2560·2019-08-30 12:54
閱讀 2249·2019-08-29 12:37
閱讀 2428·2019-08-26 13:58