巨蟒python全棧開發-第19天 核能來襲-反射

一.今日主要內容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__
相關文章
相關標籤/搜索