• python反射


    一、反射

    反射,提供了一种更加灵活的方式让你可以实现去 对象 中操作成员(以字符串的形式去 对象 中进行成员的操作)。

    正常面向对象使用,如下创建一个类

    1. class Person(object):
    2. def __init__(self, name, wx):
    3. self.name = name
    4. self.wx = wx
    5. def show(self):
    6. message = "姓名{},微信:{}".format(self.name, self.wx)

    然后创建一个对象,通过对象调用成员

    1. user_object = Person("张三", "12345678")
    2. # 对象.成员 的格式去获取数据
    3. var = user_object.name
    4. var = user_object.wx
    5. user_object.show()
    6. # 对象.成员 的格式无设置数据
    7. user_object.name = "李四"

    反射使用

    1. user = Person("张三", "12345678")
    2. # getattr 获取成员
    3. getattr(user, "name") # user.name
    4. getattr(user, "wx") # user.wx
    5. method = getattr(user, "show") # user.show
    6. method()
    7. # 或
    8. getattr(user, "show")()
    9. # setattr 设置成员
    10. setattr(user, "name", "李四") # user.name = "吴培期"
    11. print(user.name) # 李四

    Python中提供了4个内置函数来支持反射:

    • getattr,去对象中获取成员

      v1 = getattr(对象,"成员名称")
      v2 = getattr(对象,"成员名称", 不存在时的默认值)
    • setattr,去对象中设置成员

      setattr(对象,"成员名称",值)
    • hasattr,对象中是否包含成员

      v1 = hasattr(对象,"成员名称") # True/False
    • delattr,删除对象中的成员

      delattr(对象,"成员名称")

    以后如果再遇到 对象.成员 这种编写方式时,均可以基于反射来实现。

    案例

    1. class Account(object):
    2. def login(self):
    3. pass
    4. def register(self):
    5. pass
    6. def index(self):
    7. pass
    8. def run(self):
    9. name = input("请输入要执行的方法名称:") # index register login xx run ..
    10. account_object = Account()
    11. method = getattr(account_object, name,None) # index = getattr(account_object,"index")
    12. if not method:
    13. print("输入错误")
    14. return
    15. method()

    二、一些皆对象

    在Python中有这么句话:一切皆对象。 每个对象的内部都有自己维护的成员。

    • 对象是对象

      1. class Person(object):
      2. def __init__(self,name,wx):
      3. self.name = name
      4. self.wx = wx
      5. def show(self):
      6. message = "姓名{},微信:{}".format(self.name,self.wx)
      7. user_object = Person("张三","123456")
      8. user_object.name

    • 类是对象

      1. class Person(object):
      2. title = "张三"
      3. Person.title
      4. # Person类也是一个对象(平时不这么称呼)

    • 模块是对象

      1. import re
      2. re.match
      3. # re模块也是一个对象(平时不这么称呼)。

    由于反射支持以字符串的形式去对象中操作成员【等价于 对象.成员 】,所以,基于反射也可以对类、模块中的成员进行操作。

    简单粗暴:只要看到 xx.oo 都可以用反射实现。

    1. class Person(object):
    2. title = "张三"
    3. v1 = Person.title
    4. print(v1)
    5. v2 = getattr(Person,"title")
    6. print(v2)
    1. import re
    2. v1 = re.match("\w+","dfjksdufjksd")
    3. print(v1)
    4. func = getattr(re,"match")
    5. v2 = func("\w+","dfjksdufjksd")
    6. print(v2)

    三、import_module + 反射

    在Python中如果想要导入一个模块,可以通过import语法导入;也可以通过字符串的形式导入。

    示例一:

    1. # 导入模块
    2. import random
    3. v1 = random.randint(1,100)
    1. # 导入模块
    2. from importlib import import_module
    3. m = import_module("random")
    4. v1 = m.randint(1,100)

    示例二:

    1. # 导入模块exceptions
    2. from requests import exceptions as m
    1. # 导入模块exceptions
    2. from importlib import import_module
    3. m = import_module("requests.exceptions")

    示例三:

    1. # 导入模块exceptions,获取exceptions中的InvalidURL类。
    2. from requests.exceptions import InvalidURL
    1. # 错误方式
    2. from importlib import import_module
    3. m = import_module("requests.exceptions.InvalidURL") # 报错,import_module只能导入到模块级别。
    1. # 导入模块
    2. from importlib import import_module
    3. m = import_module("requests.exceptions")
    4. # 去模块中获取类
    5. cls = m.InvalidURL

    在很多项目的源码中都会有 import_module 和 getattr 配合实现根据字符串的形式导入模块并获取成员,例如:

    1. from importlib import import_module
    2. path = "openpyxl.utils.exceptions.InvalidFileException"
    3. module_path,class_name = path.rsplit(".",maxsplit=1) # "openpyxl.utils.exceptions" "InvalidFileException"
    4. module_object = import_module(module_path)
    5. cls = getattr(module_object,class_name)
    6. print(cls)

    我们在开发中也可以基于这个来进行开发,提高代码的可扩展性

  • 相关阅读:
    总结:企业开发中,如何利用webService获取第三方公司传递过来的数据。
    Java网络编程中匿名端口
    进销存软件与ERP有哪些差异?
    OpenAI首届开发者大会多项更新汇总
    互联网Java工程师面试题·Java 总结篇·第三弹
    23款奔驰GLC260L升级原厂 360全景影像 新款透明底盘
    鸿蒙工程目录介绍
    MongoDB安装及进程介绍
    VM系列振弦采集模块传感器激励方法
    MyBatis多条件查询、动态SQL、多表操作、注解开发详细教程
  • 原文地址:https://blog.csdn.net/qq_34491508/article/details/133941776