首页 > 编程语言 >Python面向对象之反射

Python面向对象之反射

时间:2024-01-14 17:15:47浏览次数:39  
标签:反射 run name plugin Python 面向对象 print hasattr

反射

【一】什么是反射

  • 反射是一种程序可以访问、检测和修改其本身状态或行为的能力。
  • 在 Python 中,反射主要指通过字符串的形式操作对象的属性。

【二】Python中的反射

  • 通过字符串的形式操作对象相关的属性。
  • python中的一切事物都是对象(都可以使用反射)

【三】反射方法

class A:
    def __init__(self, name):
        self.name = name

    def run(self):
        print(f"{self.name}在跑")

a= A('cat')

【1】getattr

getattr(object, name[, default])

  • 获取对象的属性值,如果属性不存在,可提供默认值。
print(getattr(a, 'name'))  # cat

print(getattr(a, 'age'))  # AttributeError: 'A' object has no attribute 'age'

# 获取对象中的值,如果不存在则报错,但是可以指定不存在的时候返回的默认值
print(getattr(person,'sex',None))
# 如果获取的是对象中的函数,那会直接返回函数的内存地址,可以直接调用该函数
res = getattr(person,'run')

【2】hasattr

hasattr(object, name)

  • 判断对象是否具有指定属性,如果存在就返回 True,不存在就返回 False
print(hasattr(a, 'name'))  # True
print(hasattr(a, 'age'))  # False

【3】setattr

setattr(object, name, value)

  • 设置对象的属性值
print(hasattr(a, 'age'))  # False
setattr(a, 'age', 18)
print(getattr(a, 'age'))  # 18
def eat():
    print(f'在吃饭')
a = A('cat')

setattr(a, 'eat', eat)
getattr(a, 'eat')
a.eat()  # 在吃饭

【4】delattr

delattr(object, name)

class Person:
    name='as'
    def __init__(self, age):
        self.age = age

    def run(self):
        print("跑步")
        
per = Person('tom') 
  • 如果是类,可以删除自己的数据属性和函数属性
delattr(Person, 'name')
delattr(Person, 'run')

print(hasattr(Person, 'name'))  # False
print(hasattr(Person, 'run'))  # False
  • 如果是对象,只能删除自己的 数据属性

  • 删除类中的数据属性,不能删除对象中的父类中的数据属性

delattr(per, 'name') # 报错
delattr(per, 'age')
delattr(per, 'run') # 报错

【四】类也是对象

  • 只有类经过初始化以后。,才会将 init 中属性加载到对象中
  • 类没有初始化的时候,是不会存在init里面的属性的
print(hasattr(A, 'name'))  # False
print(hasattr(A, 'run'))  # True

【五】反射当前模块中的成员

import sys

def d1():
    ...

module = sys.modules[__name__]

print(hasattr(module, 'sys'))  # True
print(hasattr(module, 'd1'))  # True

【六】反射的好处

【1】实现可插拔机制

  • 反射的好处就是,可以事先定义好接口,接口只有在被完成后才会真正执行,这实现了即插即用,这其实是一种‘后期绑定’,意味着可以在程序运行过程中动态地绑定接口的实现。

  • 这种灵活性使得程序更容易扩展和维护

class Interface:
    def run(self):
        pass


class A(Interface):
    def run(self):
        print("插件A被启动")


class B(Interface):
    def run(self):
        print("插件B被启动")


def run_plugin(plugin):
    plugin.run()


# 使用反射调用插件
plugin_name = input("请输入插件名字(A or B)  :>>>> ")
# 从全局名称空间中获取到 插件名字对应的类
plugin_class = globals().get(plugin_name)

# 判断一下当前类是否存在 并且 判断当前类是否 有 PluginInterface 接口
if plugin_class and issubclass(plugin_class, Interface):
    # 如果都成立会触发相应的方法
    run_plugin(plugin_class())
else:
    # 不存在则抛出异常
    print("Invalid plugin name")

【2】动态导入模块(基于反射当前模块成员)

  • 动态导入模块是指在程序运行时根据字符串的形式导入模块。
  • 通过反射,可以动态导入模块的成员,实现更灵活的代码组织和管理。
module_name = input("请输入模块名 :>>>> ")
method_name = input("请输入方法名 :>>>> ")

try:
    # 动态导入模块
    module = importlib.import_module(module_name)
    # 反射是否存在当前方法
    method = getattr(module, method_name)
    # 如果存在则执行当前方法
    method()
except ImportError:
    print(f"找不到模块 {module_name}")
except AttributeError:
    print(f"模块 {module_name} 中不存在方法 {method_name}")

标签:反射,run,name,plugin,Python,面向对象,print,hasattr
From: https://www.cnblogs.com/unrealqcc/p/17963900

相关文章

  • different python version + venv
    ubuntu系统上安装不同python版本https://www.bandwagonhost.net/7309.html比如安装Python3.7:sudoaptinstallpython3.7或者安装Python3.6:sudoaptinstallpython3.6安装之后,我们就可以使用Python对应版本了,比如看一下Python3.7的具体版本:python3.7-V构造应......
  • 反射机制
    01-反射的举例通过使用反射前后的例子的对比,回答:1.面向对象中创建对象,调用指定结构(属性、方法)等功能,可以不使用反射,也可以使用反射。请问有什么区别?不使用反射,我们需要考虑封装性。比如:出了Person类之后,就不能调用Person类中私有的结构使用反射,我们可以调用运行时类中任意......
  • python二分法查找
    比如要在列表arr中查找xdeff(arr,x):left=0right=len(arr)whileleft<right:mid=(left+right)//2ifmid<x:left=midelifmid>x:right=midelse:returnmid......
  • [Python急救站]学生管理系统链接数据库
    相信很多人在初学Python的时候,经常最后作业就是完成一个学生管理系统,但是我们来做一个完美的学生管理系统,并且将数据储存到数据库里。我们先看看我们的数据库怎么设置。首先呢,我选择用的是SQLServer然后,我们的数据库名称为学生管理系统 接着,新建一张表,我设置表的名称为学生......
  • Python3环境安装
    Ubuntu下自带Python。python3-Vpython3--versionPython3.10.12sudoapt-getinstallpython3-pippip -Vpip3--versionpip22.0.2from/usr/lib/python3/dist-packages/pip(python3.10)sudoaptinstallpython3.10-venvpython3-mvenvmyenvsourcemyenv/bin/activ......
  • Python Flask Class类默认方法(函数)
    前言全局说明Class类默认方法(函数)一、安装flask模块二、引用模块三、启动服务模块安装、引用模块、启动Web服务方法,参考下面链接文章:https://www.cnblogs.com/wutou/p/17963563四、Class类默认方法(函数)默认方法(函数)说明备注init类被调用后,自动执行......
  • Python Flask 模块安装、引用模块、启动Web服务方法
    前言全局说明模块安装、引用模块、启动服务一、安装flask模块官方源:pip3installflask==2.3.2国内源:pip3installflask==2.3.2-ihttp://pypi.douban.com/simple/--trusted-hostpypi.douban.com以上二选一,哪个安装快用哪个flask安装时间2023-11更多国内源:......
  • Python教程(24)——全方位解析Python中的装饰器
    Python装饰器是一种特殊的函数,它接收一个函数作为参数,然后返回一个新的函数,用于扩展或修改原始函数的行为。装饰器提供了一种便捷的方式来在不修改被装饰函数源代码的情况下,增加、修改或包装函数的功能。通俗点说就是尽量不修改原有功能代码的情况下,给原有的功能添加新的功能。装......
  • 深入了解 Python MongoDB 查询:find 和 find_one 方法完全解析
    在MongoDB中,我们使用find()和find_one()方法来在集合中查找数据,就像在MySQL数据库中使用SELECT语句来在表中查找数据一样查找单个文档要从MongoDB的集合中选择数据,我们可以使用find_one()方法。find_one()方法返回选择中的第一个文档。示例查找customers集合中......
  • 深入了解 Python MongoDB 查询:find 和 find_one 方法完全解析
    在MongoDB中,我们使用find()和find_one()方法来在集合中查找数据,就像在MySQL数据库中使用SELECT语句来在表中查找数据一样查找单个文档要从MongoDB的集合中选择数据,我们可以使用find_one()方法。find_one()方法返回选择中的第一个文档。示例查找customers集合......