Python反射介绍( 二 )

Out:
I can't walk{'age': 22, 'height': 180, 'weight': 60}应用下面介绍两种Python反射的应用场景 。
动态调用从前面举的例子中,我们了解到可以通过字符串来获取对象的属性(getattr()),这是非常有用的一个功能 。比如,一个类中有很多方法,它们提供不同的服务,通过输入的参数来判断执行某个方法,一般的使用如下写法:
class MyService():def service1(self):print("service1")def service2(self):print("service2")def service3(self):print("service3")if __name__ == '__main__':Ser = MyService()s = input("请输入您想要的服务: ").strip()if s == "service1":Ser.service1()elif s == "service2":Ser.service2()elif s == "service3":Ser.service3()else:print("error!")如果函数比较少这样写没有太大问题,如果有很多,这样写就比较复杂了,需要写大量else语句,可以使用反射机制来写:
if __name__ == '__main__':Ser = MyService()s = input("请输入您想要的服务: ").strip()if hasattr(Ser, s):func = getattr(Ser, s)func()else:print("error!")这样是不是简洁了很多,上面的例子中,通过反射,将字符串变成了函数,实现了对对象方法的动态调用 。
动态属性设置可以通过setattr()方法进行动态属性设置,在使用scapy库构造报文时,我们需要设置某些报文字段,然而网络协议的报文字段很多,在需要设置大量字段时,一个一个的赋值就很麻烦:
>>> ls(IP)version: BitField(4 bits)= ('4')ihl: BitField(4 bits)= ('None')tos: XByteField= ('0')len: ShortField= ('None')id: ShortField= ('1')flags: FlagsField= ('<Flag 0 ()>')frag: BitField(13 bits)= ('0')ttl: ByteField= ('64')proto: ByteEnumField= ('0')chksum: XShortField= ('None')src: SourceIPField= ('None')dst: DestIPField= ('None')options: PacketListField= ('[]')可以使用setattr()方法来赋值:
from scapy.all import *fields = {"version":4, "src":"192.168.0.1","dst":"192.168.10.1"}ip = IP()for key, val in fields.items():setattr(ip, key, val)



推荐阅读