class A: pass class B(A): pass obj = B() print(isinstance(obj,B)) print(isinstance(obj,A))
# 判斷a是不是b類(或者b類的派生類)實例化的對象 class A: pass class B(A): pass class C(B): pass print(issubclass(B,A)) print(issubclass(C,A))
# 判斷a類是不是b類(或者b的派生類)的派生類 # 思考:那麼 list str tuple dict等這些類與 Iterble類 的關係是什麼? from collections import Iterable print(isinstance([1,2,3], list)) # True print(isinstance([1,2,3], Iterable)) # True print(issubclass(list,Iterable)) # True # 由上面的例子可得,這些可迭代的數據類型,list str tuple dict等 都是 Iterable的子類。
class Foo(object): pass obj = Foo() print(obj,type(obj)) # 獲取當前對象是由那個類建立。 if type(obj) == Foo: print('obj是Foo類型')
反射的概念是由Smith在1982年首次提出的,主要是指程序能夠訪問、檢測和修改它自己狀態或行爲的一種能力(自省)。這一律唸的提出很快引起了計算機科學領域關於應用反射性的研究。它首先被程序語言的設計領域所採用,並在Lisp和麪向對象方面取得了成績。python
python面向對象中的反射:經過字符串的形式操做對象相關的屬性。python中的一切事物都是對象(均可以使用反射)瀏覽器
四個能夠實現自省的函數函數
下列方法適用於類和對象(一切皆對象,類自己也是一個對象)網站
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 = "old boy" def __init__(self): self.name = 'disman' 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[__name__] hasattr(this_module, 's1') getattr(this_module, 's2')
#一個模塊中的代碼 def test(): print('from the test') """ 程序目錄: module_test.py index.py 當前文件: index.py """ # 另外一個模塊中的代碼 import module_test as obj #obj.test() print(hasattr(obj,'test')) getattr(obj,'test')()
瞭解了反射的四個函數。那麼反射到底有什麼用呢?它的應用場景是什麼呢?this
如今讓咱們打開瀏覽器,訪問一個網站,你單擊登陸就跳轉到登陸界面,你單擊註冊就跳轉到註冊界面,等等,其實你單擊的實際上是一個個的連接,每個連接都會有一個函數或者方法來處理。spa
沒學反射以前的解決方式設計
class User: def login(self): print('歡迎來到登陸頁面') def register(self): print('歡迎來到註冊頁面') def save(self): print('歡迎來到存儲頁面') while 1: choose = input('>>>').strip() if choose == 'login': obj = User() obj.login() elif choose == 'register': obj = User() obj.register() elif choose == 'save': obj = User() obj.save()
學了反射以後解決方式code
class User: def login(self): print('歡迎來到登陸頁面') def register(self): print('歡迎來到註冊頁面') def save(self): print('歡迎來到存儲頁面') user = User() while 1: choose = input('>>>').strip() if hasattr(user,choose): func = getattr(user,choose) func() else: print('輸入錯誤。。。。')
這樣就能夠明確的感受到反射的好處對象
def func(): pass class Foo(object): def __call__(self, *args, **kwargs): pass def func(self): pass obj = Foo() print(callable(func)) print(callable(Foo)) print(callable(obj)) print(callable(obj.func))