1. 程式人生 > >假期(面向對象相關)

假期(面向對象相關)

運行 三種 類名 ati foo 創建對象 color 控制 ...

"""
一、isinstance(obj,cls) 和 issubclass(sub,super)
    isinstance(obj,cls) 檢查obj是否是類cls的對象
        class Bar(object):
            pass
        class Foo(object):
            pass
        obj = Foo()
        print(isinstance(obj,Foo))     #True
        print(isinstance(obj,Bar))     #False
    issubclass(sub,super) 檢查sub類是否是super類的子類(派生類)
        class Bar(object):
            pass
        class Foo(Bar):
            pass
        class Te(object):
            pass
        print(issubclass(Foo,Bar))    #True
        print(issubclass(Te,Bar))     #False
""" """ 二、反射:通過字符串的方式操作對象相關的屬性,python中的一切事物都是對象,都可以使用反射 hasattr(object,name) 判斷object中有沒有一個name字符串對應的方法或者是屬性 getattr(object,name,default=None) 從object中獲取name屬性,如果沒有返回默認值None setattr(obj,x,y) 給obj對象設置屬性x=y delattr(obj,x) 刪除對象obj裏的x屬性 類也是對象,也可以有這四個方法 使用方法測試: class Foo(object): name = "我是你的什麽啊?" def __init__(self,addr): self.addr = addr obj = Foo("去你大爺的") print(hasattr(obj,"name")) #True print(getattr(obj,"name")) #我是你的什麽啊? setattr(obj,"sb",True) print(obj.__dict__) #{‘addr‘: ‘去你大爺的‘, ‘sb‘: True} delattr(obj,"sb") print(obj.__dict__) #{‘addr‘: ‘去你大爺的‘} 反射當前模塊成員: import sys def s1(): print("s1") def s2(): print("s2") this_module = sys.modules[__name__] print(hasattr(this_module,"s1")) 使用反射的好處: 實現代碼的可插拔機制;在導入模塊方面經常使用反射;動態的導入模塊 三、__setattr__,__delattr__,__getattr__; #__setattr__添加/修改屬性會觸發它的執行 #__delattr__刪除屬性的時候會觸發 #__getattr__只有在使用點調用屬性且屬性不存在的時候才會觸發 四、二次加工標準類型(包裝) class List(list): #繼承list所有的屬性,也可以派生出自己新的,比如append和mid def append(self, p_object): ‘ 派生自己的append:加上類型檢查‘ if not isinstance(p_object,int): raise TypeError(‘must be int‘) super().append(p_object) #調用父類的append方法 @property def mid(self): ‘新增自己的屬性‘ index=len(self)//2 return self[index] 實現授權的關鍵點就是覆蓋__getattr__方法 import time class FileHandle: def __init__(self,filename,mode=‘r‘,encoding=‘utf-8‘): self.file=open(filename,mode,encoding=encoding) def write(self,line): t=time.strftime(‘%Y-%m-%d %T‘) self.file.write(‘%s %s‘ %(t,line)) def __getattr__(self, item): return getattr(self.file,item) f1=FileHandle(‘b.txt‘,‘w+‘) f1.write(‘你好啊‘) f1.seek(0) print(f1.read()) f1.close() 五、__getattribute__: 和__getattr__類似,不過不管是否存在都會執行 class Foo: def __init__(self,x): self.x = x def __getattribute__(self, item): print("我總會執行") obj = Foo(10) print(obj.x) print(obj.xxx) !當getattr和getattribute同事存在的時候只執行getattribute,除非拋出異常,兩者一起執行 六、描述符(__get__,__set__,__delete__): 什麽是描述符:描述符的本質就是一個新式類,在這個新式類中至少實現了__get__(),__set__(),__delete__()中的一個 這也被稱為描述符協議 __get__():調用一個屬性的時候觸發 __set__():為一個屬性賦值的時候觸發 __delete__():刪除屬性的時候觸發 class Foo: #這個類稱為描述符 def __get__(self, instance, owner): pass def __set__(self, instance, value): pass def __delete__(self, instance): pass 描述符的作用:用來代理另外一個類的屬性(必須把描述符定義為這個類的類屬性,不能定義到構造方法中) 分類: 數據描述符:至少實現了__get__() 和__set__()方法 非數據描述符:沒有實現__set__()方法 註意事項: 1、描述符本身應該定義為新式類,被代理的類也應該是新式類 2、必須定義為類屬性,不能定義到構造函數中 3、要嚴格遵循優先級,優先級由高到低分別是(類屬性,數據描述符,實例屬性,非數據描述符,找不到的時候觸發__getattr__()) 描述符的使用: 描述符的總結: 六、property: 一個靜態屬性property本質就實現了get,set,delete三種方法 用法一: class Foo: @property def AAA(self): print("get的時候運行") @AAA.setter def AAA(self,value): print("set的時候運行",value) @AAA.deleter def AAA(self): print("delete 的時候運行") obj = Foo() obj.AAA #get obj.AAA = "aaa" #set del obj.AAA #delete 用法二: class Foo: def get_AAA(self): print("get的時候yunx") def set_AAA(self,value): print("set 的時候運行") def delete_AAA(self): print("delete的時候運行") AAA=property(get_AAA,set_AAA,delete_AAA) #內置的property三個參數必須與get,set,delete一一對應 七、__setitem__,__getitem__,__delitem__: 示例代碼; class Foo: def __init__(self,name): self.name = name def __getitem__(self, item): print(self.__dict__[item]) def __setitem__(self, key, value): self.__dict__[key] = value def __delitem__(self, key): print("del obj 時執行") def __delattr__(self, item): print("del obj 執行,") self.__dict__.pop(item) obj = Foo("sb") obj["age"] = 18 obj["age1"] = 19 del obj.age1 del obj["age"] obj["name"] = "alex" print(obj.__dict__) 八、__str__,__repr__,__format__: 改變對象的字符串顯示__str__,__repr__,當你打印對象的時候假如裏面沒有這兩個方法,那麽打印出來的你是看不懂的 自定義格式化字符串:__format__ str函數或者print函數--->obj.__str__() repr或者交互式解釋器--->obj.__repr__() 如果__str__沒有被定義,那麽就會使用__repr__來代替輸出 註意:這倆方法的返回值必須是字符串,否則拋出異常 - 示例: format_dict={ ‘nat‘:‘{obj.name}-{obj.addr}-{obj.type}‘,#學校名-學校地址-學校類型 ‘tna‘:‘{obj.type}:{obj.name}:{obj.addr}‘,#學校類型:學校名:學校地址 ‘tan‘:‘{obj.type}/{obj.addr}/{obj.name}‘,#學校類型/學校地址/學校名 } class School: def __init__(self,name,addr,type): self.name=name self.addr=addr self.type=type def __repr__(self): return ‘School(%s,%s)‘ %(self.name,self.addr) def __str__(self): return ‘(%s,%s)‘ %(self.name,self.addr) def __format__(self, format_spec): if not format_spec or format_spec not in format_dict: format_spec=‘nat‘ fmt=format_dict[format_spec] return fmt.format(obj=self) s1=School(‘oldboy1‘,‘北京‘,‘私立‘) print(‘from repr: ‘,repr(s1)) print(‘from str: ‘,str(s1)) print(s1) print(format(s1,‘nat‘)) print(format(s1,‘tna‘)) print(format(s1,‘tan‘)) print(format(s1,‘asfdasdffd‘)) 九、__slots__: 在類中寫一個slots,在吧類中的某些字段寫在裏面,外部才可以訪問,不寫訪問不到 十、__next__和__iter__實現叠代器協議 模擬實現range方法: class Range: def __init__(self,n,stop,step): self.n=n self.stop=stop self.step=step def __next__(self): if self.n >= self.stop: raise StopIteration x=self.n self.n+=self.step return x def __iter__(self): return self for i in Range(1,7,3): # print(i) 十一、__doc__ - 顯示描述信息,即註釋信息 - 無法被繼承 十二、__module__和__class__ - __module__ 表示當前操作的對象在哪個摸快 - __class__表示當前操作的對象的類是什麽 十三、__del__: - 析構方法:當對象在內存中被釋放時執行這段代碼 - 比如在數據庫鏈接中關閉數據庫,文件操作中的close操作 十四、__enter__和__exit__: __enter__在進來的時候執行 __exit__在出去的時候執行 - 對象調用前後執行這兩個方法 十五、__call__方法: - 對象後邊+括號自動觸發執行 - 構造方法的執行是由創建對象觸發的,即對象=類名();而對於__call__方法是對象()或者類()() 十六、metaclass exec:三個參數 字符串形式的命令 全局作用域 局部作用域 exec會在指定的局部作用域內執行字符串內的代碼,除非明確地使用global關鍵字 - 類也是對象 - 什麽是元類 - 元類是類的類,類的模板 - 元類是用來控制如何創建類的,正如類是創建對象的模板一樣,而元類的主要目的是為了控制類的創建行為元類的實例化的結 果為我們用class定義的類,正如類的實例為對象(f1對象是Foo類的一個實例,Foo類是 type 類的一個實例)type是python的一 個內建元類,用來直接控制生成類,python中任何class定義的類其實都是type類實例化的對象 - 創建類的兩張方式: - 方式一:使用class關鍵字 - 方式二:手動模擬class創建類的過程 - 類名 - 類的父類 - 類體 #類名 class_name=‘Chinese‘ #類的父類 class_bases=(object,) #類體 class_body= country=‘China‘ " def __init__(self,name,age): self.name=name self.age=age def talk(self): print(‘%s is talking‘ %self.name) " - 一個類沒有聲明自己的元類,默認它的元類就是type,除了使用元類type,用戶也可以通過繼承type倆自定義元類 - #元類控制類的實例化過程: 1 類(),調用元類.__call__() 2 在1的方法中調用: 類.__new__() #返回類的對象obj 類.__init__(obj,...) #為對象進行初始化 - 元類控制類本身的產生過程
"""

假期(面向對象相關)