通过字符串映射或修改程序运行时的状态、属性、方法, 可以通过下面这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