反射 通過字元串映射或修改程式運行時的狀態、屬性、方法, 有以下4個方法 1、getattr(object, name[, default]) -> value Get a named attribute from an object; getattr(x, 'y') is equivalent t ...
反射
通過字元串映射或修改程式運行時的狀態、屬性、方法, 有以下4個方法
1、getattr(object, name[, default]) -> value
Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.
When a default argument is given, it is returned when the attribute doesn't
exist; without it, an exception is raised in that case.
判斷類中是否有指定的方法,如下:
class Dog(object): def __init__(self,name): self.name = name def eat(self): print("%s is eating......" %self.name) d = Dog("alex") choice = input(">>:").strip() #用戶輸入函數,判斷函數是否存在,存在執行,反射來判斷執行 print(hasattr(d,choice))
運行如下:
>>:talk
False
>>:eat
True
我們知道,有時候我們要根據用戶輸入來判斷類中是否有某種方法,這樣我們就能執行了。如何去判斷呢?可以使用hasattr(object,name)方法。上面,我們實現了動態判斷方法,如果存在返回True,否則返回False。
2、getattr(object, name[, default]) -> value
Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.
When a default argument is given, it is returned when the attribute doesn't
exist; without it, an exception is raised in that case.
class Dog(object): def __init__(self,name): self.name = name def eat(self): print("%s is eating......" %self.name) d = Dog("alex") choice = input(">>:").strip() #用戶輸入函數,判斷函數是否存在,存在執行,反射來判斷執行 print(getattr(d,choice))
運行結果如下:
>>:tall
Traceback (most recent call last):
File "/home/zhuzhu/第七天/get_attr.py", line 11, in <module>
print(getattr(d,choice))
AttributeError: 'Dog' object has no attribute 'tall'
>>:eat
<bound method Dog.eat of <__main__.Dog object at 0x7fecf92428d0>>
從上面可以看出,getattr()是獲取屬性的記憶體地址,如果存在返回記憶體地址,如果不存在,則返回錯誤,提示類中不存在這個方法。
既然getattr()存在放回方法的記憶體地址,那麼加上括弧執行一下,如下:
class Dog(object): def __init__(self,name): self.name = name def eat(self): print("%s is eating......" %self.name) d = Dog("alex") choice = input(">>:").strip() #用戶輸入函數,判斷函數是否存在,存在執行,反射來判斷執行 getattr(d,choice)()
運行結果如下:
>>:eat
alex is eating......
從上面可以看出,程式正常執行了,通過上面,我們可以發現,hasattr()和getattr()經常結合一起使用,hasattr()判斷是否有這個方法,而getattr()用來執行。如果存在,則調用getattr()進行執行。如下:
class Dog(object): def __init__(self,name): self.name = name def eat(self): print("%s is eating......" %self.name) d = Dog("alex") choice = input(">>:").strip() #用戶輸入函數,判斷函數是否存在,存在執行,反射來判斷執行 if hasattr(d,choice): '''這種場景在很多情況下都使用,比如讓用戶輸入某個功能,如果存在執行,不存在則告訴用戶沒有這個功能''' getattr(d,choice)() else: print("您輸入的方法不存在,請核對後重新輸入:")
運行結果如下:
>>:eat #存在執行方法
alex is eating......
>>:tall #不存在,提示方法沒有
您輸入的方法不存在,請核對後重新輸入
從上面代碼可以看出,能夠實現動態用戶輸入判斷方法是否存在,存在執行,不存在提示的功能。
下麵是實現帶參數的情況:
class Dog(object): def __init__(self,name): self.name = name def eat(self,food): print("%s is eating......%s" %(self.name,food)) d = Dog("alex") choice = input(">>:").strip() #用戶輸入函數,判斷函數是否存在,存在執行,反射來判斷執行 if hasattr(d,choice): '''這種場景在很多情況下都使用,比如讓用戶輸入某個功能,如果存在執行,不存在則告訴用戶沒有這個功能''' func = getattr(d,choice) func("chenronghua") #getattr(d,choice)("chenronghua") else: print("您輸入的方法不存在,請核對後重新輸入:")
運行結果如下:
>>:eat
alex is eating......chenronghua
也可以判斷屬性是否存在,如下,就判斷裡面單純的屬性,得到屬性值:
class Dog(object): def __init__(self,name): self.name = name def eat(self,food): print("%s is eating......%s" %(self.name,food)) d = Dog("alex") choice = input(">>:").strip() #用戶輸入函數,判斷函數是否存在,存在執行,反射來判斷執行 if hasattr(d,choice): '''這種場景在很多情況下都使用,比如讓用戶輸入某個功能,如果存在執行,不存在則告訴用戶沒有這個功能''' func = getattr(d,choice) print(func) # func("chenronghua") #getattr(d,choice)("chenronghua") else: print("您輸入的方法不存在,請核對後重新輸入:")
運行結果如下:
>>:name
alex
3.setattr(obj, name, value, /)
Sets the named attribute on the given object to the specified value.
setattr(x, 'y', v) is equivalent to ``x.y = v''
添加動態屬性:
class Dog(object): def __init__(self,name): self.name = name def eat(self,food): print("%s is eating......%s" %(self.name,food)) def talk(self): print("%s is talking....." %self.name) def laugh(self): print("%s is laughing....." %self) d = Dog("alex") choice = input(">>:").strip() #用戶輸入函數,判斷函數是否存在,存在執行,反射來判斷執行 if hasattr(d,choice): '''這種場景在很多情況下都使用,比如讓用戶輸入某個功能,如果存在執行,不存在則告訴用戶沒有這個功能''' func = getattr(d,choice) print(func) # func("chenronghua") #getattr(d,choice)("chenronghua") else: #setattr(d,choice,laugh) #動態添加一個屬性 setattr(d,"alex","sb") #動態加入一個屬性 print(getattr(d,"alex"))
運行結果如下:
>>:alex
sb
添加動態方法:
class Dog(object): def __init__(self,name): self.name = name def eat(self,food): print("%s is eating......%s" %(self.name,food)) def talk(name): print("%s is talking....." %name) def laugh(self): print("%s is laughing....." %self) d = Dog("alex") choice = input(">>:").strip() #用戶輸入函數,判斷函數是否存在,存在執行,反射來判斷執行 if hasattr(d,choice): '''這種場景在很多情況下都使用,比如讓用戶輸入某個功能,如果存在執行,不存在則告訴用戶沒有這個功能''' func = getattr(d,choice) print(func) # func("chenronghua") #getattr(d,choice)("chenronghua") else: setattr(d,choice,laugh) #動態添加一個屬性 #setattr(d,"alex","sb") #動態加入一個屬性 print(getattr(d,choice)("alex"))
其實,setattr(obj,name_str,屬性/方法)就是把一個屬性/方法賦值給name_str,如果第三參數是一個方法,那麼就賦值了一個方法給name_str,如果第三參數是一個屬性,那麼就賦值一個屬性給name_str,是屬性,使用getattr(obj,name_str)得到的是一個字元串;是方法,使用get(obj,name_str)得到的是一個方法的記憶體地址,其實本質還是上面的getattr(),方法就要看是否有參數,有參數就加入參數調用執行,沒有參數就直接加括弧執行。
4.delattr(obj, name, /)
Deletes the named attribute from the given object.
delattr(x, 'y') is equivalent to ``del x.y''
class Dog(object): def __init__(self,name): self.name = name def eat(self,food): print("%s is eating......%s" %(self.name,food)) def talk(name): print("%s is talking....." %name) def laugh(self): print("%s is laughing....." %self) d = Dog("alex") choice = input(">>:").strip() #用戶輸入函數,判斷函數是否存在,存在執行,反射來判斷執行 if hasattr(d,choice): '''這種場景在很多情況下都使用,比如讓用戶輸入某個功能,如果存在執行,不存在則告訴用戶沒有這個功能''' func = getattr(d,choice) print(func) # func("chenronghua") #getattr(d,choice)("chenronghua") else: setattr(d,choice,laugh) #動態添加一個屬性 #setattr(d,"alex","sb") #動態加入一個屬性 getattr(d,choice)("alex") delattr(d,choice) #刪除屬性或者方法 getattr(d, choice)("alex")
delattr(obj,name_str)刪除實例中的方法或者屬性。
反射:
hasattr(obj,attr),判斷一個對象里是否有對應的字元串的方法
getattr(obj,name_str),根據字元串去獲取obj對象里對應的方法的記憶體地址。
setattr(obj,name_str,z)等價於obj.name_str = z
delattr(obj,name_str)刪除實例彙總的方法或屬性
class Dog(object): def __init__(self,name): self.name = name def eat(self,food): print("%s is eating......%s" %(self.name,food)) def talk(name): print("%s is talking....." %name) def laugh(self): print("%s is laughing....." %self) d = Dog("alex") choice = input(">>:").strip() #用戶輸入函數,判斷函數是否存在,存在執行,反射來判斷執行 set_what = input("把那個變數賦值給屬性:").strip() if hasattr(d,choice): getattr(d,choice) else: setattr(d,choice,laugh) v = getattr(d,choice) if type(v) == str: print(v) else: print(v("alex"))
運行結果如下:
>>:alex
把那個變數賦值給屬性:sb
alex is laughing.....
None
上面實例是對setattr()的進一步補充,其實就是設置屬性或者方法。