一.isinstance和issubclass
isinstance(obj,cls)檢查是否obj是否是類(lèi) cls 的對(duì)象
issubclass(sub, super)檢查sub類(lèi)是否是 super 類(lèi)的派生類(lèi)
View Code
輸出結(jié)果如下
View Code
二.反射和相關(guān)的內(nèi)置函數(shù)
反射是指程序可以訪問(wèn)、檢測(cè)和修改它自己本身狀態(tài)或者行為的一種能力(自省)。
而在Python中,反射其實(shí)就是通過(guò)字符串的形式訪問(wèn)或者修改對(duì)象的屬性。這里的對(duì)象是指一切對(duì)象,類(lèi)本身也是一個(gè)對(duì)象。
1 class People: 2 country = 'china' 3 def __init__(self,name,sex): 4 self.name = name 5 self.sex = sex 6 def walk(self): 7 print('walk') 8 p1 = People('silver_bullet','male') 9 print(hasattr(p1,'name')) #hasattr(*args, **kwargs) 驗(yàn)證有沒(méi)有該屬性10 print(getattr(p1,'sex')) #getattr(object, name, default=None) 獲取一個(gè)屬性,可以設(shè)置default11 print(setattr(p1,'age',22)) #setattr(x, y, v) 設(shè)置一個(gè)屬性,返回值為None,所以用下面get方法驗(yàn)證12 print(getattr(p1,'age'))13 print(delattr(p1,'age')) #delattr(x, 'y') is equivalent to del x.y 刪除一個(gè)屬性,返回值為None14 # print(getattr(p1,'age')) #age屬性已經(jīng)被刪除掉15 setattr(p1,'show_name',lambda self:self.name+' is excellent')#增加一個(gè)函數(shù)屬性16 print(p1.show_name(p1))
模塊級(jí)別的反射
1 import sys2 xxx = 1113 this_module = sys.modules[__name__] #獲取當(dāng)前模塊4 print(hasattr(this_module,'xxx'))5 print(getattr(this_module,'xxx'))6 setattr(this_module,'yyy','12345')7 print(getattr(this_module,'yyy'))
反射的好處
實(shí)現(xiàn)可插拔機(jī)制。可以事先定義好接口,接口只有在被完成后才會(huì)真正執(zhí)行,這實(shí)現(xiàn)了即插即用,這其實(shí)是一種‘后期綁定’,即你可以事先把主要的邏輯寫(xiě)好(只定義接口), 然后后期再去實(shí)現(xiàn)接口的功能。
動(dòng)態(tài)導(dǎo)入模塊(基于反射當(dāng)前模塊成員)。
1 import importlib2 t = importlib.import_module('time') #通過(guò)字符串的形式導(dǎo)入模塊,推薦使用importlib3 print(t.time()) #不推薦__import__(m),m為字符串,這個(gè)是python解釋器自己使用的
三.內(nèi)置函數(shù)(__attr__相關(guān))
1 class Foo: 2 '內(nèi)置函數(shù)__attr__的使用' 3 def __init__(self,name): 4 self.name = name #這個(gè)也會(huì)觸發(fā)__setattr__的執(zhí)行 5 def __setattr__(self, key, value): #給屬性賦值都會(huì)觸發(fā)__setattr__,把key和value都賦值,可以做類(lèi)型判斷,彌補(bǔ)python沒(méi)有類(lèi)型限制 6 self.__dict__[key] = value #直接在dict字典中添加相應(yīng)的鍵值對(duì)即可,key和value都為字符串 7 print('from __setattr__') 8 def __delattr__(self, item): #del 操作會(huì)觸發(fā)這個(gè)內(nèi)置函數(shù) 9 self.__dict__.pop(item) #直接在dict字典中刪除相應(yīng)的鍵值對(duì)即可10 print('from __delattr__',type(item))# type(item)--------->str11 def __getattr__(self, item): #注意:屬性獲取不到,才會(huì)觸發(fā)這個(gè)內(nèi)置函數(shù)?。?!12 print('get__attr__---->{0},{1}'.format(item,type(item)))13 14 f = Foo('silver_bullet') #觸發(fā)__init__里就有一個(gè)賦值,即會(huì)觸發(fā)__settattr__15 f.time = 55516 print(f.__dict__)17 print(f.time)18 del f.time #觸發(fā)__del__內(nèi)置函數(shù)19 print(f.__dict__)20 f.xxx #這個(gè)才會(huì)觸發(fā)__getattr__的執(zhí)行,沒(méi)有找到xxx的屬性,而現(xiàn)在卻沒(méi)有報(bào)錯(cuò)
四.定制自己的數(shù)據(jù)類(lèi)型
繼承的方式
1 class my_list(list): #基于繼承 2 def __init__(self,seq): 3 for i in seq: 4 if not isinstance(i,str): 5 raise TypeError('This is not a str list') 6 else: 7 super().append(i) 8 def append(self, object: str): 9 if not isinstance(object,str):10 raise TypeError('must be str')11 super().append(object)12 @property13 def mid_value(self):14 mid_index = len(self)//215 return self[mid_index]16 17 l = my_list(['a'])18 print(l)19 l.append('1')20 print(l)21 print(l.mid_value)22 l.insert(0,4)23 print(l)
授權(quán)的方式
1 class my_list(): #基于授權(quán) 2 def __init__(self,seq): 3 for i in seq: 4 if not isinstance(i,str): 5 raise TypeError('This is not a str list') 6 self.seq = list((seq)) #使用一個(gè)中間屬性self.seq保存這個(gè)列表 7 def __str__(self): #override __str__,才能夠打印列表的顯示,否則打印的是一個(gè)對(duì)象地址 8 return str(self.seq) 9 def append(self, object: str): #重新定制這個(gè)append10 if not isinstance(object,str):11 raise TypeError('must be str')12 self.seq.append(object) #實(shí)際上是在這里使用13 @property14 def mid_value(self): #定制一個(gè)屬性,返回中間值。15 mid_index = len(self.seq)//216 return self.seq[mid_index]17 def __getattr__(self, item): #其余方法都使用list默認(rèn)的18 func = getattr(self.seq,item) #直接返回getattr的函數(shù)名19 return func20 def __getitem__(self, item): #加上以下三個(gè)item操作,才能夠支持索引,切片,賦值和del刪除21 return self.seq[item]22 def __setitem__(self, key, value):23 self.seq[key] = value24 def __delitem__(self, key):25 self.seq.pop(key)26 27 28 l = my_list(['a'])29 print(l)30 l.append('1')31 print(l[1])32 print(l.mid_value)33 l.insert(0,4)34 l[0]='123'35 print(l)36 print(l[1:])
五.給日志文件加時(shí)間頭
使用授權(quán)的方式重寫(xiě)open
1 import time 2 class Open: 3 'override File write' 4 def __init__(self,path,mode = 'r',encoding = 'GBK'): 5 self.fw = open(path,mode=mode,encoding=encoding) #這里要寫(xiě)成位置參數(shù)的形式,取到文件句柄賦值給self.f 6 def write(self,line): 7 now_time = time.strftime('%Y-%m-%d-%X') #字符串形式顯示time時(shí)間 8 self.fw.write('{0}\n'.format(now_time)) #添加日志文件的時(shí)間頭 9 self.fw.write(line) #寫(xiě)想要輸入到文件里面的內(nèi)容10 def __getattr__(self, item): #不想要改寫(xiě)的地方定義在__getattr__中,找不到的屬性會(huì)觸發(fā)這個(gè)內(nèi)置函數(shù)11 func = getattr(self.fw,item) #通過(guò)getattr的方法,將函數(shù)名的入口地址獲取到并且返回12 return func13 14 f = Open('a.txt','w+') #觸發(fā)__init__方法15 for i in range(2):16 f.write('11111111111\n')17 time.sleep(0.5)18 f.seek(0)19 print(f.readlines())
http://www.cnblogs.com/yangming111/p/6758328.html