• 面向对象 -- 反射(详细)


    使用对象反射

    obj . 属性名

    obj . 方法名()

    可以直接适用对象的方法和属性

    当我们只有字符串数据类型的内容的时候

    可以使用

    getattr(对象名,'方法名')() 来调用方法

    getattr(对象名,'属性名') 来调用属性

    1.使用对象反射
    class Manager:   # 管理员用户
        def __init__(self,name):
            self.name  = name
        def create_course(self):  # 创建课程
            print('in Manager create_course')
    
        def create_student(self): # 给学生创建账号
            print('in Manager create_student')
    
        def show_courses(self): # 查看所有课程
            print('in Manager show_courses')
    
        def show_students(self): # 查看所有学生
            print('in Manager show_students')
    
    不用反射
    alex = Manager('alex')
    operate_lst = ['创建课程','创建学生账号','查看所有课程','查看所有学生']
    for index,opt in enumerate(operate_lst,1):
        print(index,opt)
    num = input('请输入您要做的操作 :')
    if num.isdigit():
        num = int(num)
    if num == 1:
        alex.create_course()
    elif num == 2:
        alex.create_student()
    elif num == 3:
        alex.show_courses()
    elif num == 4:
        alex.show_students()
    
    使用反射
    alex = Manager('alex')
    operate_lst = [('创建课程','create_course'),('创建学生账号','create_student'),
                   ('查看所有课程','show_courses'),('查看所有学生','show_students')]
    for index,opt in enumerate(operate_lst,1):
        print(index,opt[0])
    num = input('请输入您要做的操作 :')
    if num.isdigit():
        num = int(num)
        if hasattr(alex,operate_lst[num-1][1]):
            getattr(alex,operate_lst[num-1][1])()
    
    
    shop 买东西类
        1.浏览商品   scan_goods
        2.选择商品 ,添加到购物车  choose_goods
        3.删除商品   delete_goods
    class Shop:
    
        def __init__(self,name):
            self.name = name
        def scan_goods(self):
            print('%s正在浏览商品'%self.name)
    
        def choose_goods(self):
            print('%s正在选择商品'%self.name)
    
        def delete_goods(self):
            print('%s正在删除商品'%self.name)
    
    s = Shop('self哥')
    s.choose_goods()
    s.scan_goods()
    s.delete_goods()
    if hasattr(s,'choose_goods'):   # 判断s对象有没有choose_goods
        func = getattr(s,'choose_goods')   # 使用s找到choose_goods对应的内存地址
        print(func)
        func()
    content = input('')
    if hasattr(s,content):   # 判断s对象有没有choose_goods
        func = getattr(s,content)   # 使用s找到choose_goods对应的内存地址
        print(func)
        func()
    opt_lst = ['scan_goods','choose_goods','delete_goods']
    for index,opt in enumerate(opt_lst,1):
        print(index,opt)
    num = int(input('num :'))
    if hasattr(s,opt_lst[num-1]):
        getattr(s,opt_lst[num-1])()
    
    和反射没关系
    for i in Shop.__dict__.keys():
        if not i.startswith('__'):
            print(i)

    使用类反射

    cls . 属性名

    cls . 方法名()

    class A:
        Country = '中国'
    
        @classmethod
        def show(cls):
            print('国家 : ',cls.Country)
    
    'Country'
    print(getattr(A,'Country'))   # print(A.Country)
    
    A.show  # getattr(A,'show')
    'show'
    getattr(A,'show')()   # A.show()

    使用模块反射

    import time

    time.time()

    import re
    ret = re.findall('d+','2985urowhn0857023u9t4')
    print(ret)
    'findall'
    getattr(re,'findall')   # re.findall
    ret = getattr(re,'findall')('d','wuhfa0y80aujeiagu')
    print(ret)
    
    def func(a,b):
        return a+b
    
    wahaha = func
    ret = wahaha(1,2)
    print(ret)
    import time
    time.time  == getattr(time,'time')
    time.time()  == getattr(time,'time')()
    
    'time'
    now  = getattr(time,'time')()
    print(now)
    
    time.sleep(1)
    print(321)
    getattr(time,'sleep')(1)   # time.sleep(1)
    print(123)

    反射本文件中的内容

    只要是出现在全局变量中的名字,都可以用 getattr(modules[__name__] , 字符串数据类型的名字) 来获得

    from sys import modules

    语法
    a = 1
    b = 2
    getattr(modules[__name__],'变量名')
    
    函数名
    def func(a,b):
        print('in func',a,b)
    
    getattr(modules[__name__],'func')   # func
    func(1,2)
    getattr(modules[__name__],'func')(1,2)   # func
    
    类名
    class Course:
        def func(self):
            print('in func')
    
    print(Course)
    'Course'
    print(getattr(modules[__name__],'Course'))   # Course
    getattr(modules[__name__],'Course')()   # 实例化的过程
    只要是a.b这种结构,都可以使用反射
    用对象类模块反射,都只有以下场景
    这种结构有两种场景
        a.b   b是属性或者变量值
            getattr(a,'b')   == a.b
        a.b()  b是函数或者方法
            a.b()
                getattr(a,'b')()
            a.b(arg1,arg2)
                getattr(a,'b')(arg1,arg2)
            a.b(*args,**kwargs)
                getattr(a,'b')(*args,**kwargs)
    如果是本文件中的内容,不符合a.b这种结构
    如果是这种方式,引用的模块就不是 from sys import modules , 而是直接引用 import sys 直接调用func() getattr(sys.modules[
    __name__],'func')() 直接使用类名 Person() getattr(sys.modules[__name__],'Person')() 直接使用变量名 print(a) getattr(sys.modules[__name__],'a') 所有的getattr都应该和hasattr一起使用 if hasattr(): getattr()

    setattr

    除了可以修改私有化的属性,还可以通过字符串数据类型的变量名,给一个对象创建一个新的属性

    但 setattr 不可绑定方法

    使用 setattr 创建了一个方法后,也只是创建在属性的内存空间中,而不是类的内存空间

    这种方法不是正常的方法

    所以 setattr 只用来绑属性

    class A:
        def qqxing(self):
            print('qqxing')
    
    alex = A()
    alex.name = 'sb'
    print(alex.name)
    setattr(alex,'name','sb')   # alex.name = 'sb'
    print(alex.name)
    
        

    deleter

    deleter(对象名,'属性')

    删除对象的一个属性

    和 setattr 一样,不能操作方法,只能操作属性

    issubclass

    判断类与类之间的关系

    其实就是判断类与类之间是否有继承关系

    issubclass(Son,Foo)

    判断Son是不是Foo的子类

    输出的结果是布尔值

    object是任何类的父类,所以 insubclass(Son,object) 的结果总是 True

    isinstance

    判断对象与类之间的关系,这个 '类' 也包括父类

    isinstance(obj,cls)

    判断obj是否是cls或cls子类的对象

    isinstance(obj,类)  判断时时承认继承关系的

    类 = type(obj) 也可以判断类与对象的关系,但只承认实例化这个对象的那个类(不承认所有的继承关系)

  • 相关阅读:
    windows启动、停止和重新启动Apache服务
    Mysql用户密码设置修改和权限分配
    MySQL数据库恢复(使用mysqlbinlog命令)
    影响MySQL性能的五大配置参数
    PHP获取文件后缀名的三种方法
    php 设计模式
    蓦然回首,那人却在灯火阑珊处
    websocket消息推送实现
    Spring任务调度之Quartz
    使用easyui的form提交表单,在IE下出现类似附件下载时提示是否保存的现象
  • 原文地址:https://www.cnblogs.com/biulo/p/10639859.html
Copyright © 2020-2023  润新知