通過字符串映射或修改程序運行時的狀態、屬性、方法, 可以通過下面這4中方法
1
2
3
4
5
6
7
8
|
''' 使用getattr(object, name_str, default=None) 方法獲取object對象里 對應的方法或者屬性的內存地址 如果是屬性:直接返回屬性值 如果是方法:返回方法的內存地址 ''' # hasattr(object,name_str) 判斷object對象是否有一個名為name_str的方法或者屬性 |
代碼演示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
# -*- coding:utf8 -*- class Person( object ): def __init__( self , name): self .name = name def fun( self ): print ( "%s正在玩耍" % self .name) p1 = Person( "某人飛" ) name_str = input ( "請輸入方法或者屬性" ).strip() # hasattr(object,name_str) 判斷object對象是否有一個名為name_str的方法或者屬性 if hasattr (p1, name_str): ''' 如果有就可以使用getattr(object, name_str, default=None) 方法獲取object對象里 對應的方法或者屬性的內存地址 如果是屬性:直接返回屬性值 如果是方法:返回方法的內存地址 ''' print ( getattr (p1, name_str , 80 )) # >>>name: 某人飛 # >>>fun : <bound method Person.fun of <__main__.Person object at 0x0000020B76A81370>> # 所以如果是方法,那么可以這么處理 a = getattr (p1, name_str) a() else : print ( "該對象沒有這些屬性和方法" ) 判斷和獲取的演示 |
如果對象沒有從鍵盤錄入的該方法,那么可以使用,setattr添加一個方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
def bulk( self ): print ( "這是在%s對象的類外部創建的方法" % self .name) class Person( object ): def __init__( self , name): self .name = name def fun1( self ): print ( "%s正在玩耍" % self .name) p1 = Person( "某人飛" ) name_str = input ( "請輸入您的方法或者屬性" ).strip() if hasattr (p1, name_str): a = getattr (p1, name_str) a() else : #如果沒有這個方法,那么為其創建一個已經存在的方法 """ setattr(p1, name_str, bulk) 為對象p1添加一個已經存在的bulk的方法,命名為name_str """ setattr (p1, name_str, bulk) a = getattr (p1, name_str) a(p1) """ 運行結果 請輸入您的方法或者屬性ui 這是在某人飛對象的類外部創建的方法 """ setattr (p1, name_str, bulk)添加方法 |
如果對象沒有從鍵盤錄入的該方法,那么可以使用,setattr添加一個屬性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
class Person( object ): def __init__( self , name): self .name = name p1 = Person( "某人飛" ) name_str = input ( "請輸入您的方法或者屬性" ).strip() if hasattr (p1, name_str): a = getattr (p1, name_str) print (a) # 也可以同setattr修該已有屬性的值 setattr (p1, name_str, "飛" ) print (p1.name) else : #如果沒有這個屬性,那么為其添加一個屬性 ,并為其設置一個默認值20 setattr (p1, name_str, 20 ) a = getattr (p1, name_str) print (a) """ 運行結果: 請輸入您的方法或者屬性name 某人飛 飛 運行結果: 請輸入您的方法或者屬性age 20 """ setattr (p1, name_str, index)添加屬性 |
刪除對象中的屬性和方法(其中方法并不能刪除)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
class Person( object ): def __init__( self , name): self .name = name def fun( self ): print ( "這是一個實例方法" ) p1 = Person( "某人飛" ) name_str = input ( "請輸入您的方法或者屬性" ).strip() if hasattr (p1, name_str): # 刪除這個對象的屬性或者方法 delattr (p1, name_str) else : pass print (p1.name) p1.fun() """ 運行結果: 請輸入您的方法或者屬性name AttributeError: 'Person' object has no attribute 'name' 運行結果: 請輸入您的方法或者屬性fun AttributeError: fun """ delattr (p1, name_str)只能刪除屬性,和動態添加的方法 |
注意:通過delattr能夠刪除通過setattr動態添加的方法,其實也是一個假象。真相是通過setattr添加的一個方法并不是真的給這個對象添加了一個方法,而是添加了一個屬性,setattr方法的第二個參數就是這個屬性的名字,然后這個屬性的值是一個指向外部函數的引用地址,所以當我們調用這個對象的屬性時,實際上是間接調用了這個函數,看起來就像是這個對象添加了一個方法一樣,但本質上仍然是添加的一個屬性。不管是setattr和delattr,其實都只能針對對象的屬性進行操作,它們對對象的方法是無法直接操作的。
到此這篇關于Python中的反射知識點總結的文章就介紹到這了,更多相關Python中的反射內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!
原文鏈接:https://www.cnblogs.com/fjfsu/p/15575227.html