反射主要是指程序能夠訪問、檢測和修改它自己狀態或行爲的一種能力(自省)。
python面向對象中的反射就是經過字符串獲取對象或者類的屬性,進行操做~,主要是對這4個方法的應用:hasattr,getattr,setattr,delattr。python
class Person: def __init__(self, name, age): self.__name = name self.__age = age def __fun(self): print(self.__class__) def say(self): print(self.__name + ' ' + str(self.__age)) # 判斷屬性是否存在 p = Person('baby', 18) print(hasattr(p, 'name')) # False print(hasattr(p, '_Person__name')) # True print(hasattr(p, 'say')) # True # 獲取屬性 fun = getattr(p, 'say') fun() # baby 18,執行反射獲取的方法 name = getattr(p, '_Person__name') print(name) # baby # 如果屬性不存在則報錯 # age = getattr(p, 'age') # 'Person' object has no attribute 'age' # 設置屬性 setattr(p, 'sex', 'male') # 設置的是對象的屬性,存放在對象的名稱空間中 # 這裏設置的方法是普通方法,存放在對象的名稱空間中,self.__name不會變形爲 self._Person__name # setattr(p, 'show_name', lambda self: self.__name) setattr(p, 'say_hello', lambda self: 'Hello ' + self._Person__name) print(p.__dict__) # {'_Person__name': 'baby', '_Person__age': 18, 'sex': 'male', 'say_hello': <function <lambda> at 0x10f7bf2f0>} print(p.say_hello(p)) # 不是綁定方法,須要手動傳值 # 刪除屬性 delattr(p, 'sex') print(p.__dict__) # {'_Person__name': 'baby', '_Person__age': 18, 'say_hello': <function <lambda> at 0x10f7bf2f0>} # 若不存在該屬性則報錯 # delattr(p, 'name') # AttributeError: name
Tip:ide
class Person: def __init__(self, name, age): self.__name = name self.__age = age self.city = 'NB' def __fun(self): print(self.__class__) def say(self): print(self.__name + ' ' + str(self.__age)) @classmethod def play(cls): print(cls.__name__) @staticmethod def sleep(): print('sleep...') # 判斷屬性是否存在 print(hasattr(Person, 'name')) # False print(hasattr(Person, '_Person__name')) # False,私有屬性 __name,__age 屬於對象 print(hasattr(Person, 'say')) # True # 獲取屬性 fun = getattr(Person, 'say') p = Person('baby', 18) fun(p) # baby 18,等同於Person.say(p),須要手動傳遞self # 如果屬性不存在 # age = getattr(Person, 'age') # 報錯,'Person' object has no attribute 'age' # 設置屬性 setattr(Person, 'sex', 'male') # 設置的是類的靜態屬性 setattr(Person, 'show_city', lambda self: self.city) # 這裏經過類設置的方法爲綁定到對象的方法,經過對象調用的時候可以自動傳值(self) print(p.show_city()) # NB # setattr(Person, 'show_name', lambda self: self.__name) # self.__name 不會自動轉換爲 self._Person__name # print(p.show_name()) # AttributeError: 'Person' object has no attribute '__name' # 刪除屬性 delattr(Person, 'sex') # 刪除的是類的靜態屬性 # 獲取類方法 getattr(Person, 'play')() # 會完成自動傳值,默認將Person做爲第一個參數傳遞給play方法 # 獲取靜態方法 getattr(Person, 'sleep')()
Tip:this
import sys def s1(): print('s1') def s2(): print('s2') this_module = sys.modules[__name__] # 判斷模塊中是否存在 s1 方法 print(hasattr(this_module, 's1')) # True # 獲取模塊中的方法並執行 getattr(this_module, 's2')() # s2
sys.modules[__name__] 也能夠寫成 sys.modules['__main__'],可是不建議這麼寫,由於當前的模塊被導入到另一個模塊的時候,這個被導入的模塊使用 sys.modules['__main__'] 就獲取不到它的內存地址了~
操做的對象也能夠是導入的模塊code
# module_test def test(): print('from test') # test.py import module_test print(hasattr(module_test,'test')) # True getattr(module_test, 'test')() # from test
isinstance 方法用來判斷 一個對象 和 一個類之間的關係,即這個對象是否是由這個類實例化而來對象
class Person: pass p = Person() print(isinstance(p, Person)) # True
issubclass 用來判斷兩個類之間是否存在繼承關係繼承
class Father: pass class Son(Father): pass print(issubclass(Son, Father)) # True
.................^_^ip