• python-面向对象之反射


    反射

    描述

    反射就是指在程序运行时,动态的去确定对象的类型,并且可以通过字符串的的形式去调用对应的属性,方法,导入模块,是一种基于字符串的事件驱动

    举一个例子:

    class Student:
        def __init__(self):
            self.name = 'mhy'
            self.price = '5000'
    
    obj1 = Student()
    content = input('>>>:')  # 这里输入的name是字符串
    
    # 如果不知道反射,我们平常都是这么根据输入调用的
    if content == 'name':
        print(obj1.name)
    elif content == 'price':
        print(obj1.price)
    

    但是上面的方法,我们如果要调用成百上千的个方法或者属性,不得死了,所以就有了反射这种方法

    python提供了几个内置函数来解决这种事情getattr() hasattr()

    例如上面的例子,我们现在可以这样做,代码如下

    对象的反射

    • getattr(对象,字符串形式属性或者方法名) 返回对象中属性名对应的值
    • hasattr(对象,字符串形式属性或者方法名) 返回的是一个bool值,判断对象中是否存在属性

    反射属性

    val = getattr(对象,'属性名') val就是属性的值

    class Student:
        def __init__(self):
            self.name = 'mhy'
            self.price = '5000'
    obj1 = Student()
    content = input('>>>:')  
    if hasattr(obj1, content): # 判断obj1对象中是否存在该属性
        ret = getattr(obj1,content) # 对象和输入的字符串
        print(ret)
    

    反射方法

    方法的反射如果我们使用上面属性的反射的话,会有问题

    比如属性是不需要加括号的,直接会返回值,但是方法不加括号只会返回内存地址,但是我们如何判断当前是否是个方法,还是个属性呢.这里要用到判断了

    callable() : 判断参数是否可调用

    val = getattr('对象','方法名')

    val就是方法的地址

    val() ==> 调用方法

    代码如下:

    class Student:
        def __init__(self):
            self.name = 'mhy'
            self.price = '5000'
    
        def show_name(self):
            print(self.name,self.price)
            
    obj1 = Student()
    content = input('>>>:')  
    if hasattr(obj1, content):
        ret = getattr(obj1,content)
        if callable(ret): # 判断ret是否可调用,因为有可能是一个内存地址
            ret()
        else:
            print(ret)
    

    类的反射

    class A:
         role = 'China'
            
    print(getattr(A,'role'))  # 用类获取类的变量
    

    模块的反射

    # 模块的反射
    import time
    print(time.time())
    print(getattr(time,'time')())
    

    反射本质:a.b ===== getattr(a,'b')

    反射使用:

    name = 'alex'
    age = 84
    def func():
        print('wahaha')
    class Student():pass
    
    import sys
    # 反射变量
    ret1 = getattr(sys.modules[__name__],'name')
    ret2 = getattr(sys.modules[__name__],'age')
    # 反射函数
    getattr(sys.modules[__name__],'func')()
    # 反射类
    print(getattr(sys.modules[__name__],'Student'))
    

    学生例子

    class Studnet:
        opt_lst = [
            ('查看可选课程', 'show_courses'),
            ('选择课程', 'choose_course'), 
            ('查看已选课程', 'show_selected_course'),
            ('退出', 'quit')
            ]
        def __init__(self,name):
            self.name = name
            self.courses = []
        def show_courses(self):
            print('查看一共有多少门课程')
    
        def choose_course(self):
            print('选择课程')
    
        def show_selected_course(self):
            print('查看已经选择的课程')
    
        def quit(self):
            print('退出')
    
    stu = Studnet('alex')
    for index,opt in enumerate(Studnet.opt_lst,1):
        print(index,opt[0])
    num = int(input('请输入您要选择的操作序号:'))
    if hasattr(stu,Studnet.opt_lst[num-1][1]):
        getattr(stu,Studnet.opt_lst[num-1][1])()
    
  • 相关阅读:
    gulp和webpack的区别和联系
    Cesium-CesiumWidget, Viewer, Scene三者之间的关系
    node-gpy
    Cesium与Threejs结合
    【每日一具1】Morin 魔音一款支持手机、电脑的音乐软件,全网歌曲免费听/下载
    Python网络爬虫(实践篇)
    Python网络爬虫(浏览器伪装技术)
    Python网络爬虫(理论篇)
    【每日一具1】Morin 魔音一款支持手机、电脑的音乐软件,全网歌曲免费听/下载
    永久免费,搞定全网音乐!
  • 原文地址:https://www.cnblogs.com/Anesthesia-is/p/11977023.html
Copyright © 2020-2023  润新知