反射:python
用字符串數據類型的變量名來訪問這個變量的值程序員
反射的方法:網絡
getattr hasattr setattr delattr函數
getattr: 命名空間.方法名或屬性 == getattr(命名空間,'方法名或屬性') 得到類中變量的值 若變量不存在則報錯spa
hasattr: 判斷類中指定變量是否存在,返回bool值 能夠配合getattr使用操作系統
class Student: ROLE = 'STUDENT' @classmethod def check_course(cls): print('查看課程了') @staticmethod def login(): print('登陸') # 反射查看屬性 # print(Student.ROLE) # print(getattr(Student,'ROLE')) # 反射調用方法 方法名不對的時候會報錯 # getattr(Student,'check_course')() # 類方法 # getattr(Student,'login')() # 靜態方法 num = input('>>>') if hasattr(Student,num): 判斷方法名在指定類中是否存在,返回bool值 getattr(Student,num)()
####getattr用途很普遍,基本命名空間.方法名或屬性名 這類語句均可以用getattr替代 好比 對象
# import os # # os.rename('__init__.py','init') # # getattr(os,'rename')('init','__init__.py') # == os.rename # rename = os.rename # rename2 = getattr(os,'rename') # rename2('__init__.py','init') # os.rename('__init__.py','init') # rename('init','init2') # os.rename('init','init2')
####反射本身模塊中的內容 找到本身當前文件所在的命名空間blog
def wahaha():
print('wahaha')
def qqxing():
print('qqxing')
wahaha() qqxing() import sys print(sys.modules) # import 都至關於導入了一個模塊 #模塊哪一個導入了 哪一個沒導入 在個人python解釋器裏應該記錄下來 import sys #是一個模塊,這個模塊裏的全部的方法都是和python解釋器相關的 # sys.modules #這個方法 表示全部在當前這個python程序中導入的模塊 # '__main__': <module '__main__' from 'D:/sylar/python_workspace/day20/4.反射.py'> #自身模塊在modules中的鍵值對 print(sys.modules['__main__']) my_file = sys.modules['__main__'] my_file.wahaha() my_file.qqxing() # 'qqxing' # 'wahaha' getattr(my_file,'wahaha')() getattr(my_file,'qqxing')()
setattr:修更名稱內存
delattr:刪除指定方法或屬性資源
class A: def __init__(self,name): self.name = name a = A('alex') # a.name = 'alex_SB' # getattr(a,'name') setattr(a,'name','alex_SB') #修改對象屬性 print(a.name) print(a.__dict__) del a.name print(a.__dict__) delattr(a,'name') #刪除對象屬性 print(a.__dict__)
__名字__
類中的特殊方法\內置方法
雙下方法
魔術方法 magic_method
類中的每個雙下方法都有它本身的特殊意義
__call__ 至關於 對象()
__len__ len(obj)
__new__ 開闢內存空間的 類的構造方法
寫一個單例類=
__del__ 析構方法,與__new__相對應 垃圾回收機制
全部的魔術方法都是在外部執行內置函數或者特殊語句而自動在內部執行的,不須要在外部額外出發
__call__:
class A: def __call__(self, *args, **kwargs): print('執行__call方法了') def call(self): print('執行call方法了') class B: def __init__(self,cls): print('在實例化A以前作一些事情') self.a = cls() self.a() print('在實例化A以後作一些事情') a = A() a() # 對象() == 至關於調用__call__方法 a.call() A()() # 類名()() ,至關於先實例化獲得一個對象,再對對象(),==>和上面的結果同樣,至關於調用__call__方法 B(A) 將A類當作參數傳進B類進行實例化
__len__:
# 內置函數和類的內置方法是有姦情的 # len(dict) # len(tuple) str list set class mylist: def __init__(self): self.lst = [1,2,3,4,5,6] self.name = 'alex' self.age = 83 def __len__(self): print('執行__len__了') return len(self.__dict__) l = mylist() print(len(l)) # len(obj)至關於調用了這個obj的__len__方法 # __len__方法return的值就是len函數的返回值 # 若是一個obj對象沒有__len__方法,那麼len函數會報錯
__new__:
__new__ ==> 構造方法
__init__ ==>初始化方法
class Single: def __new__(cls, *args, **kwargs): # print('在new方法裏') obj = object.__new__(cls) print('在new方法裏',obj) return obj def __init__(self): print('在init方法裏',self) # 1.先執行__new__方法,開闢一個屬於對象的空間 # 2.把對象的空間傳給self,執行init # 3.將這個對象的空間返回給調用者 obj = Single()
單例類:
class Cls: __COND=None def __new__(cls, *args, **kwargs): if not Cls.__COND : Cls.__COND=object.__new__(Cls) return Cls.__COND def __init__(self,name): self.name=name c1=Cls('alex') c2=Cls('kangkang') print(c1) print(c2) #兩次打印的內存地址同樣,說明只開闢了一個對象空間 print(c1.name) print(c2.name) #由於只開闢了一個對象空間,因此後續實例化的對象屬性會覆蓋前面的屬性
__del__ 析構方法 垃圾回收機制
#構造方法 申請一個空間 #析構方法 釋放一個空間以前執行 #某對象借用了操做系統的資源,還要經過析構方法歸還回去 : 文件資源 網絡資源 #垃圾回收機制 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 = 'alex' def read(self): self.f.read(1024) def __del__(self): # 是去歸還/釋放一些在建立對象的時候借用的一些資源 # del 對象的時候 程序員觸發 # python解釋器的垃圾回收機制 回收這個對象所佔得內存的時候 python自動觸發的 self.f.close() f = File('文件名') f.read() #無論是主動仍是被動,這個f對象總會被清理掉,被清理掉就觸發__del__方法,觸發這個方法#就會歸還操做系統的文件資源 #python解釋器在內部就能搞定的事兒 #申請一起空間 操做系統分配給你的 #在這一起空間以內的全部事兒 歸你的python解釋器來管理 a = 1 del a 對象 --> 內存 f = open('wenjian') # python --> 操做系統 --> 硬盤裏的文件 --> 文件操做符 f.close() # 文件操做符 del f