一. 反射
什么是反射
反射的概念是由Smith在1982年首次提出的,主要是指程序可以訪問、檢測和修改它本身狀態或行為的一種能力(自省)。這一概念的提出很快引發了計算機科學領域關於應用反射性的研究。它首先被程序語言的設計領域所采用,並在Lisp和面向對象方面取得了成績。
反射就是用字符串數據類型的變量名去訪問變量.
反射中適用於類和對象的方法:
getattr
setattr
hasattr
delattr
反射情景:
類名反射 : 靜態屬性 類屬性 靜態方法
對象反射: 對象屬性 對象方法
模塊: 模塊中的方法
自己的模塊中
反射的參數:
getattr : (命名空間 , ' 變量名 ')
setattr : (命名空間 , ' 變量名 ' , 新值)
hasattr : (命名空間 , ' 變量名 ')
delattr : (命名空間 , ' 變量名 ')
class Foo: f = '類的靜態變量' def __init__(self,name,age): self.name=name self.age=age def say_hi(self): print('hi,%s'%self.name) obj=Foo('egon',73) print(hasattr(obj,'name')) #檢測是否含有某屬性 print(hasattr(obj,'say_hi')) #檢測是否含有某屬性 n=getattr(obj,'name') #獲取屬性 print(n) func=getattr(obj,'say_hi') #獲取屬性 func() print(getattr(obj,'aaaaaaaa','不存在啊')) #報錯 setattr(obj,'sb',True) # #設置屬性 setattr(obj,'show_name',lambda self:self.name+'sb') # #設置屬性 print(obj.__dict__) print(obj.show_name(obj)) delattr(obj,'age') # # 刪除屬性 delattr(obj,'show_name') # # 刪除屬性 delattr(obj,'show_name111')#不存在,則報錯 print(obj.__dict__)

類也是對象
class Foo(object): staticField = "boy" def __init__(self): self.name = 'peiqi' def func(self): return 'func' @staticmethod #靜態方法 def bar(): return 'bar' print (getattr(Foo, 'staticField')) print (getattr(Foo, 'func')) print (getattr(Foo, 'bar'))

反射當前模塊
還可以導入其他模塊,利用反射查找該模塊是否存在某種方法.
import sys def s1(): print('s1') def s2(): print ('s2') this_module = sys.modules['__main__'] #__main__表示當前文件 print(hasattr(this_module, 's1')) #判斷's1'是否在當前文件的方法名中 getattr(this_module, 's2')() #取出
二. 內置方法/魔術方法/雙下方法
__名字__ 不是被直接調用的
間接調用: 內置函數/面向對象中的特殊語法/python提供的語法糖(語法糖: 相對簡單的語法)
__call__ : 通過 對象() 調用 用類寫裝飾器
__len__ : len(obj) , 要求obj必須實現了__len__ , 要求這個方法的返回值必須是數字int類型
__new__ : 在實例化的過程中,最先執行的方法, 在執行__init__之前, 用來創造一個對象,構造方法
__init__ : 在實例化的過程中,在__new__執行之后, 自動觸發的一個初始化方法
__str__ : str(obj) ,要求必須事項__str__, 要求這個方法的返回值必須是字符串str類型
可在 : print %s str中使用
__repr__ : 是__str__的備胎, 如果有__str__方法,那么 print %s str 都會先去執行__str__方法,並且使用__str__的返回值
如果沒有__str__, 那么 print %s str 都會執行__repr__方法
__repr__ 可在 :repr(obj) , %r 中使用
在子類中使用__str__,先找子類的__str__,如果沒有的話就向上面的父類里面找__str__方法,只要父類不是object,並且父類中有__str__方法,就執行父類的__str__
但是如果除了object之外的父類都沒有__str__方法, 就執行子類的__repr__方法,如果子類沒有__repr方法__,就像上面的父類找__repr__方法,如果在object類之前都沒有__repr__方法,就執行object類中的__str__方法.
class A: def __init__(self,name): self.name = name def __str__(self): return '**%s**'%self.name def __repr__(self): return self.name class B(A): def __init__(self,name): self.name = name def __repr__(self): return '***' a = B('xxx') print(a) print(str(a),repr(a)) print('%s | %r'%(a,a)) class A: def __init__(self,name): self.name = name # def __str__(self): # return '**%s**'%self.name def __repr__(self): return self.name class B(A): def __init__(self,name): self.name = name def __repr__(self): return '***' a = B('xxx') print(a) print(str(a),repr(a)) print('%s | %r'%(a,a))

構造方法 申請一個空間
析構方法 釋放一個空間
某對象借用了操作系統的資源,還要通過析構方法歸還回去 : 文件資源 網絡資源
# 垃圾回收機制 class A: def __del__(self): # 析構方法 del A的對象 會自動觸發這個方法 print('執行我了') a = A() del a # 對象的刪除 del print(a) class File(): # 處理文件的 def __init__(self,file_path): self.f = open(file_path) self.name = 'xd' def read(self): self.f.read(1024) def __del__(self): # 是去歸還/釋放一些在創建對象的時候借用的一些資源 # del 對象的時候 程序員觸發 # python解釋器的垃圾回收機制 回收這個對象所占得內存的時候 python自動觸發的 self.f.close() f = File('文件名') f.read() # 不管是主動還是被動,這個f對象總會被清理掉,被清理掉就觸發__del__方法,觸發這個方法就會歸還操作系統的文件資源
在內置模塊中
有一些特殊的方法, 要求對象必須事現__getitem__/__setitem__才能使用
class B: def __init__(self,lst): self.lst = lst def __getitem__(self, item): return self.lst[item] def __setitem__(self, key, value): self.lst[key] = value def __delitem__(self, key): self.lst.pop(key) b = B(['111','222','ccc','ddd']) print(b.lst[0]) #__getitem__ print(b[0]) b[3] = 'xxx' #__setitrm__ print(b.lst) del b[2] #__delitem__ print(b.lst)
hash方法:
底層數據結構基於hash值尋址的優化操作
hash是一個算法
hash能夠把某一個要存在內存里的值經過一系列計算, 保證不同值的hash結果是不一樣的
對同一個值在多次執行python代碼的時候hash值是不同的, 但對同一個值, 在同一次執行python代碼的時候hash值永遠不變
集合去重復原理
__eq__方法
class A: def __init__(self,name,age): self.name = name self.age = age def __eq__(self, other): if self.name == other.name and self.age == other.age: return True a = A('xd',83) aa = A('xd',83) aa2 = A('xd',83) aa3 = A('xd',83) aa4 = A('xd',83) aa5 = A('xd',83) aa6 = A('xd',83) print(a,aa) print(aa3 == aa == aa4)

可以判斷某一個對象的某一個參數和其他對象的相同位置參數是否相同