Python面向对象之反射
1392 字
7 分钟
Python面向对象之反射
【一】反射
【1】什么是反射
- 反射是一种程序可以访问、检测和修改其本身状态或行为的能力。
- 在 Python 中,反射主要指通过字符串的形式操作对象的属性。
【2】Python中的反射
- 通过字符串的形式操作对象相关的属性。
- python中的一切事物都是对象(都可以使用反射)
【二】反射方法
【1】反射方法介绍
- getattr(object, name[, default])
- 获取对象的属性值,如果属性不存在,可提供默认值。
- hasattr(object, name)
- 判断对象是否具有指定属性
- setattr(object, name, value)
- 设置对象的属性值
- delattr(object, name)
- 删除对象的属性
【2】反射方法使用
(1)引入
class Person: def __init__(self, name, age): self.name = name self.age = age
def run(self): print("人能跑 ...")
person = Person('dream', 18)
# 直接通过对象获取属性对应的值print(person.name)# dream
# 可以查看类的属性,不能查看方法print(person.__dict__)# {'name': 'dream', 'age': 18}
# 根据字典取值:拿到字典中对应的值print(person.__dict__['name'])# dream
# 查看对象中的所有方法print(person.__dir__())
# 查看 对象中 的所有方法print(dir(person))# ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'name', 'run'](2)getattr
- getattr(object, name[, default])
- 获取对象的属性值,如果属性不存在,可提供默认值。
class Person: def __init__(self, name, age): self.name = name self.age = age
def run(self): print("人能跑 ...")
person = Person('dream', 18)
# getattr 方法 : 如果存在这个方法或者属性,就返回属性值或者方法的内存地址;如果不存在,报错res_name = getattr(person, 'name')print(f"res_name :>>>> {res_name}")# res_name :>>>> dream
res_age = getattr(person, 'age')print(f"res_age :>>>> {res_age}")# res_age :>>>> 18
res_run = getattr(person, 'run')print(f"res_run :>>>> {res_run}")# res_run :>>>> <bound method Person.run of <__main__.Person object at 0x000002405665B9A0>>
res_smile = getattr(person, 'smile')print(f"res_smile :>>>> {res_smile}")r'''Traceback (most recent call last): File "E:\PythonProjects\000.py", line 72, in <module> res_smile = getattr(person, 'smile')AttributeError: 'Person' object has no attribute 'smile''''(3)hasattr
- hasattr(object, name)
- 判断对象是否具有指定属性
# 常用# hasattr 判断对象是否存在某属性或方法class Person: def __init__(self, name, age): self.name = name self.age = age
def run(self): print("人能跑 ...")
person = Person('dream', 18)
# getattr 方法 : 如果存在这个方法或者属性,就返回属性值或者方法的内存地址;如果不存在,报错res_name = hasattr(person, 'name')print(f"res_name :>>>> {res_name}")# res_name :>>>> True
res_age = hasattr(person, 'age')print(f"res_age :>>>> {res_age}")# res_age :>>>> True
res_run = hasattr(person, 'run')print(f"res_run :>>>> {res_run}")# res_run :>>>> True
res_smile = hasattr(person, 'smile')print(f"res_smile :>>>> {res_smile}")# res_smile :>>>> False(4)setattr
- setattr(object, name, value)
- 设置对象的属性值
# 常用# setattr 给对象设置方法或属性class Person: def __init__(self, name, age): self.name = name self.age = age
def run(self): print("人能跑 ...")
person = Person('dream', 18)
# getattr 方法 : 如果存在这个方法或者属性,就返回属性值或者方法的内存地址;如果不存在,报错res_name = hasattr(person, 'name')print(f"res_name :>>>> {res_name}")# res_name :>>>> True
res_age = hasattr(person, 'age')print(f"res_age :>>>> {res_age}")# res_age :>>>> True
res_run = hasattr(person, 'run')print(f"res_run :>>>> {res_run}")# res_run :>>>> True
# 没有 height 属性 ----> 社会属性 值setattr(person, 'height', 180)
print(getattr(person, 'height'))# 180
def smile(): print("可以笑")
# 设置方法setattr(person, 'smile', smile)# 获取方法print(getattr(person, 'smile'))# 使用方法person.smile()(5)delattr
- delattr(object, name)
- 删除对象的属性
# 常用# setattr 给对象设置方法或属性class Person: def __init__(self, name, age): self.name = name self.age = age
def run(self): print("人能跑 ...")
person = Person('dream', 18)
res_name = delattr(person, 'name')print(f"res_name :>>>> {res_name}")# res_name :>>>> True
res_name = getattr(person, 'name')print(res_name)【3】拓展
(1)类也是对象
- 在Python中一切皆对象,所以我们也可以将类作为反射方法的第一个参数,反射其属性
# hasattr 判断对象是否存在某属性或方法class Person: def __init__(self, name, age): self.name = name self.age = age
def run(self): print("人能跑 ...")
# getattr 方法 : 如果存在这个方法或者属性,就返回属性值或者方法的内存地址;如果不存在,报错res_name = hasattr(Person, 'name')print(f"res_name :>>>> {res_name}")# res_name :>>>> False
res_age = hasattr(Person, 'age')print(f"res_age :>>>> {res_age}")# res_age :>>>> False
res_run = hasattr(Person, 'run')print(f"res_run :>>>> {res_run}")# res_run :>>>> True
res_smile = hasattr(Person, 'smile')print(f"res_smile :>>>> {res_smile}")# res_smile :>>>> False(2)反射当前模块成员
import sys
def s1(): print('s1')
def s2(): print('s2')
this_module = sys.modules[__name__]
res_s1 = hasattr(this_module, 's1')print(res_s1)# True
res_s2 = getattr(this_module, 's2')print(res_s2)# <function s2 at 0x000002C2425E35B0>【三】反射的好处
【1】实现可插拔机制
- 反射的好处就是,可以事先定义好接口,接口只有在被完成后才会真正执行,这实现了即插即用,这其实是一种‘后期绑定’,意味着可以在程序运行过程中动态地绑定接口的实现。
- 这种灵活性使得程序更容易扩展和维护。
class PluginInterface: def execute(self): pass
class PluginA(PluginInterface): def execute(self): print("插件A被启动")
class PluginB(PluginInterface): def execute(self): print("插件B被启动")
def run_plugin(plugin): plugin.execute()
# 使用反射调用插件plugin_name = input("请输入插件名字(PluginA or PluginB) :>>>> ")# 从全局名称空间中获取到 插件名字对应的类plugin_class = globals().get(plugin_name)
# 判断一下当前类是否存在 并且 判断当前类是否 有 PluginInterface 接口if plugin_class and issubclass(plugin_class, PluginInterface): # 如果都成立会触发相应的方法 run_plugin(plugin_class())else: # 不存在则抛出异常 print("Invalid plugin name")【2】动态导入模块(基于反射当前模块成员)
- 动态导入模块是指在程序运行时根据字符串的形式导入模块。
- 通过反射,可以动态导入模块的成员,实现更灵活的代码组织和管理。
import importlib
module_name = input("请输入模块名 :>>>> ")method_name = input("请输入方法名 :>>>> ")
try: # 动态导入模块 module = importlib.import_module(module_name) # 反射是否存在当前方法 method = getattr(module, method_name) # 如果存在则执行当前方法 method()except ImportError: print("Module not found")except AttributeError: print("Method not found")支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!
相关文章智能推荐
1
C 语言发展史
编程语言了解 C 语言从 BCPL、B 语言到现代标准 C 的发展历程、核心特点与应用领域。
2
C 语言开发环境的安装与配置
编程语言在 Windows、Linux 与 macOS 上安装 C 工具链,配置编辑器,并编译运行第一个 C 程序。
3
C 语言初识:程序运行机制与基本结构
编程语言认识 C 程序从源代码到运行的完整流程,以及基础语法和程序的基本结构。
4
C 语言基础:注释、关键字、变量与数据类型
编程语言学习 C 语言的注释、关键字、标识符、常量、变量和基本数据类型等基础知识。
5
C 语言数据类型
编程语言理解 C 语言的数据类型体系,包括基本类型、整数类型、浮点类型和逻辑类型。
随机文章随机推荐














