反射主要是指程序能够访问、检测和修改其自己状态或行为的一种能力。在Python中最重要的4个方法以下所示:html
咱们先来定义一个类,以下所示:python
class Fruit: def __init__(self,name,color): self.name=name self.color=color def __str__(self): return f"Fruit is {self.name} color is {self.color}" def buy(self,price,totalWeight): return f"Fruit is {self.name},total price is {price*totalWeight}"
getattr主要用来获取指定字符串名称的对象属性,其使用方法以下所示:微信
getattr(object, name:string[, default]) -> value
- name参数须要为string类型,无论是判断类属性仍是类方法,其名称均以字符串形式传参
- 若是属性存在,则返回其属性值,不存在则分为两种状况,一种是没有default参数时,则直接报错,如给定了default参数,对象没有其属性,则返回给定的default值
- 若是获取的是类方法,则返回函数对象
之前面定义的Fruit类为例app
# 实例化一个类 apple=Fruit("apple","red") # 利用反射获取类属性 print(getattr(apple,"name")) print(getattr(apple,"color")) # 利用反射获取类方法 print(getattr(apple,"buy")) # 利用反射获取不存在的属性且有默认值 print(getattr(apple,"test","123")) # 利用反射获取不存在的属性且没有默认值 - 报错 print(getattr(apple,"test"))
输出结果以下所示:函数
apple red <bound method Fruit.buy of <__main__.Fruit object at 0x000001E70B356288>> 123 Traceback (most recent call last): File "C:/Users/Surpass/Documents/PycharmProjects/SADCI/TempCode/reflectorSample.py", line 24, in <module> print(getattr(apple,"test")) AttributeError: 'Fruit' object has no attribute 'test'
setattr主要用于给对象添加一个类属性,若是添加的属性已经存在,则对其进行更新,不然则进行建立,其使用方法以下所示:测试
setattr(object, name:string, value)
name参数须要为string类型,无论是判断类属性仍是类方法,其名称均以字符串形式传参ui
示例以下所示:code
# 实例化一个类 apple=Fruit("apple","red") # 为实例添加一个类属性,并设置其值 setattr(apple,"destination","china") print(f'第一次添加类属性,其值为(添加操做):{getattr(apple,"destination")}') setattr(apple,"destination","USA") print(f'第二次添加类属性,其值为(更新操做):{getattr(apple,"destination")}')
输出结果以下所示:htm
第一次添加类属性,其值为(添加操做):china 第二次添加类属性,其值为(更新操做):USA
hasattr经常使用于判断对象中是否存在其属性或方法,经常使用用法以下所示:对象
hasattr(object, name:string) -> bool
name参数须要为string类型,无论是判断类属性仍是类方法,其名称均以字符串形式传参
示例以下所示:
# 实例化一个类 apple=Fruit("apple","red") # 判断属性或方法是否存在 print(f'对象是否存在其属性 name - {True if hasattr(apple,"name") else False }') print(f'对象是否存在其属性 country - {True if hasattr(apple,"country") else False }') print(f'对象是否存在其方法 buy - {True if hasattr(apple,"buy") else False }')
输出结果以下所示:
对象是否存在其属性 name - True 对象是否存在其属性 country - False 对象是否存在其方法 buy - True
delattr经常使用于删除指定的属性,但不能用于方法,经常使用用法以下所示:
delattr(object, name:string)
name参数须要为string类型,无论是判断类属性仍是类方法,其名称均以字符串形式传参
示例以下所示:
# 实例化一个类 apple=Fruit("apple","red") delattr(apple,"name") # 判断属性或方法是否存在 print(f'对象是否存在其属性 name - {True if hasattr(apple,"name") else False }') print(f'对象是否存在其属性 country - {True if hasattr(apple,"country") else False }') print(f'对象是否存在其方法 buy - {True if hasattr(apple,"buy") else False }')
输出结果以下所示:
对象是否存在其属性 name - False 对象是否存在其属性 country - False 对象是否存在其方法 buy - True
在平常使用,通常会进行判断属性是否存在,而后再调用获取、添加和删除方法
如下用一个简单的示例来解释,反射在实际的应用案例。如今有一个场景,就是根据传入的不一样的模块名称,调用不一样的模块所对应方法,代码以下所示:
class ReflectSample: def moduleA(self): print("我是moduleA") def moduleB(self): print("我是moduleB") def moduleC(self): print("我是moduleC") def moduleD(self): print("我是moduleD")
while True: reflectSample=ReflectSample() choice=input("请输入模块名称") if choice == "moduleA": reflectSample.moduleA() elif choice == "moduleB": reflectSample.moduleB() elif choice == "moduleC": reflectSample.moduleC() elif choice == "moduleD": reflectSample.moduleD() else: print("输入的模块不存在")
测试结果以下所示:
请输入模块名称moduleA 我是moduleA 请输入模块名称moduleD 我是moduleD 请输入模块名称moduleF 输入的模块不存在
while True: reflectSample = ReflectSample() choice = input("请输入模块名称") if hasattr(reflectSample,choice): func=getattr(reflectSample,choice) func() else: print("输入的模块不存在")
测试结果以下所示:
请输入模块名称moduleA 我是moduleA 请输入模块名称moduleD 我是moduleD 请输入模块名称moduleF 输入的模块不存在
两种方法一对比,天然就以为方法二更简洁,也更容易维护,更不用担忧类中有不少个方法。
本文地址:http://www.javashuo.com/article/p-sosyssjy-bq.html
本文同步在微信订阅号上发布,如各位小伙伴们喜欢个人文章,也能够关注个人微信订阅号:woaitest,或扫描下面的二维码添加关注: