python3高级语法:__slots__属性、property装饰器、上下文管理协议、__new__方法
#practice29:派生內置不可變類型并修改其實例化行為(以tuple為例)
__new__() is intended mainly to allow subclasses of immutable types (like int, str, or tuple) to customize instance creation.
__init__()Called after the instance has been created (by __new__()), but before it is returned to the caller.
__new__() and __init__() work together in constructing objects (__new__() to create it, and __init__() to customize it)
- 修改內置不可變類型(int/str/tuple)的實例化行為,做法是:繼承內置不可變類,并覆蓋其new方法。
- 注意:并非所有內置類都可以簡單繼承,list/dir/str繼承后重新覆蓋的某些內置方法會不起作用,即新類還會調用覆蓋前的內置方法;為保證不會發生這種情況,最好去繼承collections.UserDict/collections.UserList/collections.String
- new負責創建對象,包含創建其大部分內置方法、屬性等;init負責個性化定制(初始化)對象,即將init的參數賦值為對象屬性!
1、定制化tuple類型
必須重新定義new與init
class IntTuple(tuple):#覆蓋tuple的內置靜態方法,不需要加裝飾器def __new__(cls,iterable):g = (x for x in iterable if isinstance(x,int) and x > 0)return super(IntTuple,cls).__new__(cls,g)#參數iterable必須要有,這是數據入口,隨后該數據會被傳遞給__new__def __init__(self,iterable):print(self)#可選super(IntTuple,self).__init__()a = IntTuple([1,44,'2',(3,5)])#practice30:減小實例內存開銷
- 類屬性slots用于申明實例的所有屬性。
- dict屬性用于保存對象的所有屬性,并可以動態添加
- 在類屬性slots中排除dict屬性,即可禁止對象動態添加屬性!如:obj.qq = 100,則對象有了新屬性qq
1、 定義類屬性slots對實例屬性的影響
import sys class A():def __init__(self,id,name):self.id = idself.name = nameclass B():__slots__ = ['id','name']def __init__(self,id,name):self.id = idself.name = name print(dir(A(1,'lisi'))) print(dir(B(2,'lisi'))) print(set(dir(A(2,'lisi'))) - set(dir(B(2,'lisi')))) print(sys.getsizeof(A(1,'lisi'))) print(sys.getsizeof(A(1,'lisi').__dict__))屬性差異為紅色標記的兩個屬性,weakref對于內存的消耗可不計
practice31:讓對象支持上下文管理器
- 實現上下文管理協議主要依賴類的實例方法enter與exit
- 句法 with obj as obj1: pass ,實際執行過程為obj調用enter方法,返回的新對象賦值給obj1,之后執行塊內代碼,最后obj1執行exit方法!
1、實例
mydict = {}class A():def __init__(self,a,b):self.a = aself.b = bdef __enter__(self):mydict['a'] = self.amydict['b'] = self.b#后三個參數是固定的,異常類型,異常實例、異常traceback對象def __exit__(self,exc_type,exc_val,exc_tb):mydict.clear()print(mydict) with A(3,5) as Q:print(mydict) print(mydict)2、異常捕獲與壓制
mydict = {}class A():def __init__(self,a,b):self.a = aself.b = bdef __enter__(self):mydict['a'] = self.amydict['b'] = self.b#后三個參數是固定的,異常類型,異常實例、異常traceback對象def __exit__(self,exc_type,exc_val,exc_tb):#對于with代碼塊中出現的異常,__exit__能捕獲print(exc_type,exc_val,exc_tb)mydict.clear()#返回True能成功壓制異常!!!return Trueprint(mydict) with A(3,5) as Q:raise Exception('myerror')print(mydict) print(mydict)with代碼塊產生異常,但任然會執行exit方法,清空字典;這是上下文管理器的默認行為方式,即先執行exit后再拋出代碼塊內的異常,確保exit方法始終要執行
通過return True成功壓制異常,即有異常發生也不拋出!
#practice32:可管理的對象屬性
- 直接訪問對象屬性的形式,如:obj.x = ‘1’,這種方式調用簡單,但卻不夠靈活,例如想要檢查屬性x的值必須為int,此種方法顯然不合適;此外存在安全性問題,如上述賦值后x為str,如果后續進行數學運算,會拋出異常,在程序復雜的情況下很難查找!
使用setx/getx方法來訪問屬性,相當于中間抽象出一層,進行一些邏輯處理,比較靈活,但每次調用起來比較費勁
解決方法:內置裝飾器property
總結
以上是生活随笔為你收集整理的python3高级语法:__slots__属性、property装饰器、上下文管理协议、__new__方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 完美解决Flask-Migrate使用S
- 下一篇: 最常用git命令汇总(参考列表)