一.今日主要內容app
1.isinstance,type,issubclass
A.isinstance: 判斷你給對象是不是xx類型的. (向上判斷)
B.type: 返回xxx對象的數據類型
C.issubclass: 判斷xxx類是否xxx的子類
(1)day11介紹過是不是可迭代的和是不是迭代器
(2)issubclass( 判斷類是否爲某類的子類//查看某一個類是否爲另外一個類的派生類 )
(3)isinstance (對象;判斷類型)
(4)type:類型
2.如何區分方法和函數(代碼)
在類中:
實例方法:
若是是類名.方法 函數
若是是對象.方法 方法
類方法:都是方法
靜態方法:都是函數
from types import MethodType, FunctionType
isinstance()
3.反射(重要)
一共就4個函數(在,每一道例題中,體會,究竟是怎麼用的)
高手和水平差一點的人,就在於經驗的掌控,這就要平時多留意生活的細節,生活會眷顧有心人,屢次揣摩必有所得
attr:attrbute屬性
getattr()
從xxx對象中獲取到xxx屬性值
hasattr()
判斷xxx對象中是否有xxx屬性值
delattr()
從xxx對象中刪除xxx屬性
setattr()
設置xxx對象中的xxx屬性爲xxx值
二.今日內容大綱函數
1.isinstance&type&issubclass測試
2.區分方法和函數ui
3.反射spa
三.今日內容詳解:code
1.isinstance&type&issubclass對象
2.區分方法和函數blog
3.反射繼承
做業:內存
(1)類變量和示例變量的區別?
答案:類變量是屬於類的
示例變量是屬於實例變量的,示例變量是屬於對象的
(3)isinstance和type的區別並用代碼舉例說明?
isinstance: 判斷xxx是不是xxx類型的(向上判斷) type 返回xx對象的數據類型 ''' #本身總結 (1)注意二者的寫法是有區別的 (2)A:type()不會認爲子類是一種父類類型,不考慮繼承關係 B:isinstance() 會認爲子類是一種父類類型,考慮繼承關係 示例: class Animal: def eat(self): print('剛睡醒吃點兒東西') class Cat(Animal): def play(self): print('貓喜歡玩兒') c=Cat() print(isinstance(c,Cat)) # True c是一隻貓 print(isinstance(c,Animal)) # True print(type(c)==Cat) print(type(c)==Animal) print(type(c)) #<class '__main__.Cat'> '''
(4)
這個題目須要認真反覆研究
題目:補全代碼
def func(arg):
"""
判斷arg是否能夠被調用,若是能夠則執行並打印其返回值,
不然直接打印結果
:param arg:傳入的參數
arg:
"""
pass
def func(arg): if callable(arg): #判斷xxx是否能夠被調用 () print(arg()) else: print('不能夠被調用') # func(1) #結果執行1() 不能夠被調用 def haha(): print('呵呵') return '吼吼' func(haha) #最後執行的是 :打印'呵呵',由於打印了arg(),全部結果就有了兩個. # 結果: # 呵呵 # 吼吼 思考問題: 對象可不能夠被調用?只要類中有__call__,對象就是能夠被調用的
(5)
補全代碼(重點題目)
def func(*args):
"""
計算args中函數\方法\ Foo類對象的個數,並返回給調用者
:param args:傳入的參數
"""
pass
from types import FunctionType,MethodType class Foo: def chi(self): print('我是吃') @staticmethod def he(): print('我是he') def func(*args): #*args可能包含:方法,函數,Foo類對象 hanshu=0 fangfa=0 foo=0 for el in args: #循環完成以後打印 if isinstance(el,FunctionType): #函數 hanshu+=1 elif isinstance(el,MethodType): #方法 fangfa+=1 elif type(el)==Foo: foo+=1 print(hanshu,fangfa,foo) f1=Foo() f2=Foo() func(f1,f1,f1,f2,f2,f2,f1.chi,f1.he,Foo.chi,Foo.he) #6個對象,1個方法,3個函數 print(Foo) #打印類名 f=Foo() print(type(f)) #type打印的類
'''
結果:
3 1 6
<class '__main__.Foo'>
<class '__main__.Foo'>
'''
!!!!!!type拿到的就是類!!!!!!
有些東西真的是須要重複記憶的
(6)
class StarkConfig(object): list_display=[] #類變量是共享出去的 def get_list_display(self): self.list_display.insert(0,33) return self.list_display class RoleConfig(StarkConfig): list_display=[11,22] s1=StarkConfig() s2=StarkConfig() result1=s1.get_list_display() print(result1) result2=s2.get_list_display() print(result2) print(result1 is result2) print(s1.list_display) ''' 結果: [33] [33, 33] True [33, 33] ''' #最後的result1和result2的內存地址是同樣的,因此顯示True #要想本身建立本身的
(7)
class StarkConfig(object): list_display=[] def get_list_display(self): self.list_display.insert(0,33) return self.list_display class RoleConfig(StarkConfig): list_display = [11,22] s1=StarkConfig() s2=RoleConfig() result1=s1.get_list_display() print(result1) result2=s2.get_list_display() print(result2) #看下內存地址 print(result1 is result2) print(id(result1)) print(id(result2)) 結果: [33] [33, 11, 22] False 1762754727304 1762754727688
(8)
class StarkConfig(object): list_display=[] def get_list_display(self): self.list_display.insert(0,33) return self.list_display class RoleConfig(StarkConfig): list_display=[11,22] s1=RoleConfig() s2=RoleConfig() result1=s1.get_list_display() print(result1) result2=s2.get_list_display() print(result2) 結果: 分析同第六題的繼承 #用的是同一份類變量 結果: [33, 11, 22] [33, 33, 11, 22]
(9)
class Base(object): pass class Foo(Base): pass print(issubclass(Base,Foo)) #結果:False
(11)#重點題目,這是一道綜合的大題(有必要,反覆看,手寫多遍)
#要求:
若是有如下handler.py文件,請run.py中補充代碼實現:
獲取handler中全部成員名稱:dir(handler)
獲取handler中名字叫Base的成員
檢查其餘成員是不是Base類的子類(不包含Base),若是是則建立對象並添加到objs列表中
# #原例 # handler.py文件內的內容 class Base(object): pass class F1(Base): pass class F2(Base): pass class F3(F2): pass class F4(Base): pass class F5(object): pass class F6(F5): # pass #run,py import handler def func(): objs=[] name_list=dir(handler) #簡介:查看xx對象中的全部的內容,迭代器中用過 print(name_list) if __name__== '__main__': func() #本身測試的程序 import handler def func(): objs=[] name_list=dir(handler) #簡介:查看xx對象中的全部的內容,迭代器中用過 print(name_list) # print(dir(handler)) #整合,上邊的兩行 if __name__== '__main__': func() # 理解的知識點 # print(help(dir())) #builtins 內置函數 #老師講解:#(重點題目,須要反覆理解issubclass,type,isinstance) import handler def func(): objs=[] name_list=dir(handler) #簡介:查看xx對象中的全部的內容,迭代器中用過 print(name_list) ''' #結果是: ['Base', 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__'] ''' base=getattr(handler,'Base') #拿到Base類 print(base) ''' #結果是: <class 'handler.Base'> ''' for el in name_list: #從模塊中的全部的名字中拿到每個名字 if not el.startswith('__')and issubclass(getattr(handler,el),base)and el!='Base': #不是父類自己;不是以__開頭的;是base的子類,經過獲得每個類名;三個條件的交集 #雙下劃線開頭和結束的是模塊 #getattr(handler,el)獲得模塊裏邊的類名 objs.append(getattr(handler,el)()) #由於要放的是對象,因此要加上括號 print(objs) # print(name_list) # print(dir(handler)) #整合 if __name__== '__main__': func() ''' getattr():從xxx對象中獲取到xxx屬性值 本題是:getattr(handler,el)獲得模塊裏邊的類名 '''
(12)
#沒有思路,老師當時漏掉的小知識點 class Foo(object): def __init__(self): self.name = ' ' self.age=100 obj=Foo() setattr(obj,'email','wupeiqi@xx.com') # #請實現:一行代碼實現獲取obj中全部成員(字典類型) # # #老師講解: # # 如何拿到對象中全部的成員 print(obj.__dict__) #一句話拿到一個字典 # # 結果:{'name': ' ', 'age': 100, 'email': 'wupeiqi@xx.com'}
(13)
class Foo(object): def __init__(self): self.name=' ' self.age=100 obj=Foo() setattr(Foo,'email','wupeiqi@xx.com') #必須在Foo中加上這個信息,在對象中加會產生 # type object 'Foo' has no attribute 'email' v1=getattr(obj,'email') v2=getattr(Foo,'email') print(v1,v2) #類和對象都有 ''' wupeiqi@xx.com wupeiqi@xx.com ''' #總結:從類和對象均可以拿到屬性
(14)什麼是可迭代對象?如何將一個對象變成可迭代對象?
# A. class Foo: #類是不可迭代的 pass #'Foo' object is not iterable f=Foo() for e in f: print(e) #B. 將類變成可迭代的 class Foo: def __iter__(self): return (i for i in range(10)) #生成器表達式 f=Foo() for e in f: print(e) ''' 結果: 0 1 2 3 4 5 6 7 8 9 '''
(15)
15.如何讓一個對象能夠被執行? 在類中添加 __call__