1、反射 反射類中的變量 反射對象中的變量 反射模塊中的變量 反射本文件中的變量 1、定義:使用字符串數據類型的變量名 來獲取這個變量的值 例如: name = 'xiaoming' print(name) # xiaoming print('name') # name 平時咱們要想獲取'xiaoming'這個值,要用name去獲取,可是若是想用字符串'name' 獲取這個值呢, 就須要用到反射。 2、反射應用的場景(就是把接收的字符串轉換成變量的名字便於使用) 1,input 用戶輸入的若是是a,那麼就打印1,若是輸入的是b就打印2,若是輸入的是name,就打印xiaoming 2,文件 從文件中讀出的字符串,想轉換成變量的名字 3,網絡 將網絡傳輸的字符串轉換成變量的名字
3、反射類中的變量 : 靜態屬性,類方法,靜態方法 class Foo: School = 'Zhbit' Country = 'China' language = 'Chiness' @classmethod def class_method(cls): print('in class_method') @staticmethod def static_method(): print('in staticmethod') def hahaha(self): print('hahaha') # 若是要實現輸入School就打印對應的值,Country也打印對應的值,那麼: # 1,用判斷實現: inp = input('請輸入:') if inp == 'School':print(Foo.School) elif inp == 'Country':print(Foo.Country) elif inp == 'language':print(Foo.language) # 在屬性少的時候這樣寫,沒什麼問題,可是想想,若是有100個屬性呢,你要寫100次判斷嗎? 因此,請看反射。 # 2,反射實現 while True: inp = input('>>>') print(getattr(Foo,inp)) # OK,這就實現了,並且不管多少個屬性,均可以實現,很簡單吧! # 那麼下面就來解析反射須要用到的方法 2-1getattr方法 用法:getattr(變量名(命名空間),字符串(屬於一個命名空間內的變量名)) # 獲取靜態屬性 print(getattr(Foo,'School')) # 就等於 Foo.School print(getattr(Foo,'class_method')) # 就等於 Foo.class_method 獲得的是一個函數地址 print(getattr(Foo,'static_method')) #就等於 Foo.static_method 獲得的是一個函數地址 # 若想執行這個函數 getattr(Foo,'class_method')() # in class_method getattr(Foo,'static_method')() # in staticmethod 2-2hasattr方法 # 要是沒有這個屬性或者方法就會報錯,那麼出於安全考慮,就須要判斷有沒有這個屬性或者方法纔去執行 # 就要用到hasattr() print(hasattr(Foo,'class_method')) #True print(hasattr(Foo,'hello')) # False while True: inp = input('請輸入:') if hasattr(Foo,inp): print(getattr(Foo,inp)) 4、反射對象屬性,普通方法 class Foo: def __init__(self,name,age): self.name = name self.age = age def sleep(self): print('%s在睡覺,快打死他' %self.name) xiaobai = Foo('小白',12) print(getattr(xiaobai,'name')) getattr(xiaobai,'sleep')() 5、反射模塊中的變量 import os # os就是一個模塊 os.rename('a.txt','a.bak') getattr(os,'rename')('a.bak','a.txt') 6、反射本文件中的變量 a = 1 b = 2 age = 18 # 函數 def func(): print(666) # 類 class A:pass import sys print(sys.modules['__main__']) # 本文件的命名空間 print(sys.modules['__main__'].a) # 本文件的命名空間中的a變量的值:1 print(sys.modules['__main__'].func) # 本文件的命名空間中函數func的地址:<function func at 0x000001C735B81E18> print(sys.modules['__main__'].A) # 本文件的命名空間中類A的地址:<class '__main__.A'> # __name__ 與 '__main__' 同樣,表明本文件的命名空間 print(sys.modules['__main__']) print(sys.modules[__name__]) # 反射 print(getattr(sys.modules[__name__],'a')) # 1 print(getattr(sys.modules['__main__'],'a')) # 1 print(getattr(sys.modules[__name__],'age')) # 18 getattr(sys.modules[__name__],'func')() #執行函數func:666 obj = getattr(sys.modules[__name__],'A')() #實例化對象 print(obj) 7、setattr:增和改 # 類 class Foo: country = 'China' # 函數 def func(): print(666) print(getattr(Foo,'country')) # China setattr(Foo,'country','Big China') # 接受三個參數:命名空間 '變量名' 變量值 print(getattr(Foo,'country')) # Big China setattr(Foo,'fun',func) # 爲類Foo新增一個屬性fun,值爲func函數的地址 print(func) # <function func at 0x00000188B34F2D08> print(Foo.fun) # <function func at 0x0000026DC4A21E18> getattr(Foo,'fun')() # 666 8、delattr:刪 class Foo: language = '火星文' country = 'China' def func(): print(666) print(Foo.__dict__) delattr(Foo,'language') print(Foo.__dict__) 2、內置方法__str__和__repr__ 1、內置方法的定義 不須要程序員定義,自己就存在類中的方法就是內置方法, 它不用咱們直接調用,當遇到特定的場景就會自動觸發, 內置的方法一般都長這樣 : __名字__ 能夠叫 : 雙下方法、 魔術方法、 內置方法 好比咱們熟悉的初始化函數__init__()就是內置方法, 實例化對象的時候就自動執行 2、__str__和__repr__ __str__ 當你打印一個對象的時候print(obj) 觸發__str__ 當你使用%s格式化的輸出對象時候print('%s' %obj) 觸發__str__ str強轉數據類型的時候str(obj) 觸發__str__ __repr__ repr是str的備胎 直接打印對象,有__str__的時候執行__str__,沒有__str__的時候,執行__repr__ 當你使用%r輸出對象時候print('%r' %obj) 觸發__repr__ repr強轉數據類型的時候repr(obj) 觸發__repr__ 注意:__str__ 和__perp__都必需要用return,並且返回值必須是字符串 例子: class Fruit: def __init__(self,name,price): self.name = name self.price = price def __str__(self): return 'in str:%s的價格是:%s' %(self.name,self.price) def __repr__(self): return 'in repr:%s的價格是:%s' % (self.name, self.price) apple = Fruit('蘋果',5) # 直接打印對象,有__str__的時候執行__str__,沒有__str__的時候,執行__repr__ print(apple) # in str:蘋果的價格是:5 # 當你使用%s格式化的輸出對象時候print('%s' %obj) 觸發__str__ print('%s' %apple) # in str:蘋果的價格是:5 # 當你使用%r輸出對象時候print('%r' %obj) 觸發__repr__ print('%r' %apple) # in repr:蘋果的價格是:5 # str強轉數據類型的時候str(obj) 觸發__str__ print(str(apple)) # in str:蘋果的價格是:5 # repr強轉數據類型的時候repr(obj) 觸發__repr__ print(repr(apple)) # in repr:蘋果的價格是:5 升級: class Fruit: def __str__(self): return 'Fruit_str' def __repr__(self): return 'Fruit_repr' class Apple(Fruit): def __str__(self): return 'Apple_str' def __repr__(self): return 'Apple_repr' apple = Apple() print(apple) # apple是Apple類對象,直接打印,先從Apple類找,有__str__的時候執行Apple的__str__,沒有__str__的時候, # 從父類去找__str__,父類有就執行,若是父類沒有,就找子類的__repr__,有就執行子類的__repr__,沒有就去父類找, #父類有就執行,沒有就打印對象空間地址