1. 程式人生 > >Python實戰之反射hasattr getattr setattr delattr

Python實戰之反射hasattr getattr setattr delattr

#通過字串對映或修改程式執行時的狀態、屬性、方法, 有以下4個方法反射

class Xx():

     def method...   

#Xx=類名  method =類方法  obj=例項化的XX類物件  func=函式

hasattr : hasattr(obj, ' method')  #判斷ob該例項j繼承的類xx裡面method的方法

 

#以下配合hasattr的判斷使用:

getattr:getattr(obj, ' method')          #獲取obj該例項繼承的類xx裡面的method方法的記憶體

              getattr(obj, ' method')()        #執行該類xx裡面的method方法

setattr:setattr(obj, method,func)      #obj的繼承Xx類如果沒有該method方法,就執行函式func(obj)

setattr:setattr(obj, variable,value)    #建立修改obj屬性(變數)   obj.xx = yy這種

delattr: delattr(obj. variable)               #刪除obj的屬性(變數)   ==  del obj.xx

 

實戰
 

__author__ = "Burgess Zheng"

class Dog(object):

    def __init__(self,name):

         self.name = name

    def eat(self,food):

        print("%s is eating %s.." %(self.name,food))

d = Dog("Xiaoming")

#print(d.eat)#獲取d例項的繼承類的eat方法記憶體地址

#print(d.name)#列印d例項的屬性name的值  結果:Xiaoming

#del d.name#刪除d例項的name屬性

#print(d.name)

#hasattr和getattr的作用

'''

choice = input(">>您要做什麼:").strip()

print(hasattr(d,choice))#hasattr判斷物件是否有該方法 ()第一個:d是物件名

                        #()第2個:是否有該choice方法   choice=手動輸入

                        #簡單就是hasattr判斷d該例項的繼承類是否有choice方法 ,如果有返回true,如果沒有返回false

print(getattr(d,choice))#getattr 獲得物件的方法的記憶體地址

                        #如:chonice輸入的是eat 

                        #getattr(d,eat)==print(d.eat) :獲取例項d的eat方法記憶體地址

getattr(d,choice)()#呼叫輸入的方法的執行結果

                   #getattr(d,eat)()==d.eat() 呼叫d的繼承類的eat方法執行結果

                   #(如果eat方法有引數 如:eat(self,food)  我們就需要 d.eat("xx")

'''


#hasattr getattr判斷和呼叫

'''

choice = input(">>您要做什麼:").strip()

if hasattr(d,choice):#假如d例項的繼承類有該choice方法 #choice是手動輸入 假如:輸入eat

    func = getattr(d,choice) #func=getattr(d,eat)

                             #getattr(d,eat)==print(d.eat) 獲取例項d的eat方法記憶體地址

    food = () #由於eat(self,food)需要輸入實參

    food =input(">>您的食物:").strip()#輸入實參 假如輸入:xx

    func(food)        #func==getattr(d,eat)(xx)==d.eat(xx) 呼叫d的繼承類的eat方法執行結果

                      #得出的結果是:

                      # >>您要做什麼:eat

                      #>>您的食物:xx

                      #NiuHanYang is eating xx..

'''

 

#setattr建立方法

'''

choice = input(">>您要做什麼:").strip()

def bulk(self):

    print("%s is yelling..." %self.name)

#在本地新增一個函式,這樣的話如果要建立方法就可以呼叫該bulk函式


if hasattr(d, choice):

#假如d例項的繼承類沒有該choice方法 #choice是手動輸入 假如:輸入talk

#由於沒有talk方法 跳到else:

    func = getattr(d, choice)

    func("垃圾")

else:

    setattr(d,choice,bulk)

# setattr:d:例項物件 ,choice:輸入的方法名talk,呼叫bulk函式建立方法

# setattr 建立talk方法(這裡也可以比喻成屬性),talk的值為bulk函式

    #func = getattr(d,choice) # getattr(d,choice) == d.talk

    #func(d)   # func(d) == d.talk(d)

# 由於函式bulk有形參,所以把例項d自己傳過去作為形參

              #試驗結果:

              #>> 您要做什麼: talk

              #Xiaoming is yelling.

'''

#setattr建立更改例項的屬性

'''

choice = input(">>您要做什麼:").strip()

if hasattr(d, choice): #假如d例項有name屬性  choice是手動輸入 假如:輸入name

    attr = getattr(d,choice)#getattr(d,choice) == d.name

    print(attr)  # print(attr) == print(d.name) 獲取的是d例項的屬性name的值

                 #結果:NiuHanYang

    #attr = "xiaoming"  #d.name = "xiaoming" 修改d例項屬性name的值

    #print(attr) #結果:xiaoming

    setattr(d,choice,"xiaoming")#也可以用這種方式修改d.例項屬性name值

    print(d.name) #結果:Xiaoming



else:   #假如上面輸入的是不存在的屬性如:money

         # 跳到這裡: 自動新增屬性

   setattr(d,choice,22)#為例項d增加一個屬性money 值為 22

   print(getattr(d,choice))#print(getattr(d,choice))=print(d.money)列印顯示d例項的money屬性值

              # 試驗結果:

              #>>您要做什麼:money

              #22

'''

#刪除例項屬性

choice = input(">>您要做什麼:").strip()

if hasattr(d, choice): #假如d例項有name屬性  choice是手動輸入 假如:輸入name

   delattr(d,choice)#delattr(d,name)==del d.name 刪除d例項的name屬性

   print(d.name)