zoukankan      html  css  js  c++  java
  • 面向对象:类中的反射及其应用

    # 什么是反射?
      # 用字符串数据类型的变量名来访问这个变量的值
      # 反射的方法: getattr hasattr setattr delattr

    #引,当你没用反射时是这样的!
    class Student:
        def __init__(self,name):
            self.name = name
        def check_course(self):
            print('check_course')
        def choose_course(self):
            print('choose_course')
        def choosed_course(self):
            print('查看已选择的课程')
    stu = Student('tianba')
    num = input('>>>')
    if num == 'check_course':
        stu.check_course()
    elif num == 'choose_course':
        stu.choose_course()
    elif num == 'choosed_course':
        stu.choosed_course()
    
    #执行结果:
    >>>check_course
    check_course

    # 类 静态属性 类方法 静态方法

      # 命名空间.XXX == getattr(命名空间,'XXX')
    class Student:
        ROLE = 'STUDENT'
        @classmethod
        def check_course(cls):
            print('查看课程了')
    
        @staticmethod
        def login():
            print('登录')
    # 反射查看属性
    print(Student.ROLE)
    print(getattr(Student,'ROLE')) #第一个参数的命名空间中的变量名为第二个参数的变量的值
                #命名空间   #变量的值
    
    # 反射调用方法
    getattr(Student,'check_course')()  # 类方法
    getattr(Student,'login')()         # 静态方法
    
    num = input('>>>') #输入内容调用静态方法
    if hasattr(Student,num):
        getattr(Student,num)()
    #执行结果:
    STUDENT
    STUDENT
    查看课程了
    登录
    >>>login
    登录
    # 反射调用方法
      # getattr(Student,'check_course')() # 类方法
      #getattr(Student,'login')() # 静态方法

    # num = input('>>>') #让用户输入内容调用静态方法
    # if hasattr(Student,num):
    # getattr(Student,num)()

    # 对象

      # 方法 对象属性
    class A():
        def __init__(self,name):
            self.name = name
    
        def func(self):
            print('in func')
    
    a = A('alex')
    print(a.name)
    print(getattr(a,'name')) #一个参数为对象,第二个参数为对象的属性
    getattr(a,'func')() #使用对象去反射类的方法和对象的属性
    
    #执行结果:
    alex
    alex
    in func
    # 模块

    # import os # 别人写好的python代码的结合
    # # os.rename('__init__.py','init')
    # # getattr(os,'rename')('init','__init__.py') # == os.rename
    # rename = os.rename
    # rename2 = getattr(os,'rename')
    # rename2('__init__.py','init') # os.rename('__init__.py','init')
    # rename('init','init2') # os.rename('init','init2')

    # def wahaha():
    # print('wahaha')
    #
    # def qqxing():
    # print('qqxing')

    # 反射自己模块中的内容 找到自己当前文件所在的命名空间
    # wahaha()
    # qqxing()

    # import sys
    # print(sys.modules)
    # import 都相当于导入了一个模块
    # 模块哪个导入了 哪个没导入 在我的python解释器里应该记录下来
    # import sys 是一个模块,这个模块里的所有的方法都是和python解释器相关的
    # sys.modules 这个方法 表示所有在当前这个python程序中导入的模块
    # '__main__': <module '__main__' from 'D:/sylar/python_workspace/day20/4.反射.py'>
    # print(sys.modules['__main__'])
    # my_file = sys.modules['__main__']
    # my_file.wahaha()
    # my_file.qqxing()
    # # 'qqxing'
    # # 'wahaha'
    # getattr(my_file,'wahaha')()
    # getattr(my_file,'qqxing')()

    # 总结反射

      # hasattr,getattr

    # 类名.名字
    # getattr(类名,'名字')
    # 对象名.名字
    # getattr(对象,'名字')
    # 模块名.名字
    # import 模块
    # getattr(模块,'名字')
    # 自己文件.名字
    # import sys
    # getattr(sys.modules['__main__'],'名字')

    #反射的应用

    # 选课系统的代码
    # login
    # 判断身份 并且根据身份实例化
    # 根据每个身份对应的类 让用户选择能够做的事情
    class Manager:
        OPERATE_DIC = [
            ('创造学生账号', 'create_student'),
            ('创建课程','create_course'),
            ('查看学生信息','check_student_info'),
        ]
        def __init__(self,name):
            self.name = name
        def create_student(self):
            print('创建学生账号')
        def create_course(self):
            print('创建课程')
        def check_student_info(self):
            print('查看学生信息')
    
    class Student:
        OPERATE_DIC = [
            ('查看所有课程', 'check_course'),
            ('选择课程', 'choose_course'),
            ('查看已选择的课程', 'choosed_course')
        ]
        def __init__(self,name):
            self.name = name
        def check_course(self):
            print('check_course')
        def choose_course(self):
            print('choose_course')
        def choosed_course(self):
            print('查看已选择的课程')
    
    def login():
        username = input('user : ')
        password = input('pwd : ')
        with open('userinfo') as f:
            for line in f:
                user,pwd,ident = line.strip().split('|')   # ident = 'Manager'
                if user == username and pwd == password:
                    print('登录成功')
                    return username,ident
    
    import sys
    def main():
        usr,id = login()
        print('user,id :',usr,id)
        file = sys.modules['__main__']
        cls = getattr(file,id)     #Manager = getattr(当前文件,'Manager')
        obj = cls(usr)
        operate_dic = cls.OPERATE_DIC
        while True:
            for num,i in enumerate(operate_dic,1):
                print(num,i[0])
            choice = int(input('num >>>'))
            choice_item = operate_dic[choice-1]
            getattr(obj,choice_item[1])()
    main()
    #执行结果1:
    user : alex
    pwd : 123456
    登录成功
    user,id : alex Manager
    1 创造学生账号
    2 创建课程
    3 查看学生信息
    num >>>1
    创建学生账号
    1 创造学生账号
    2 创建课程
    3 查看学生信息
    
    #执行结果2:
    user : hezewei
    pwd : 666
    登录成功
    user,id : hezewei Student
    1 查看所有课程
    2 选择课程
    3 查看已选择的课程
    num >>>2
    choose_course
    1 查看所有课程
    2 选择课程
    3 查看已选择的课程
    num >>>3
    查看已选择的课程
    1 查看所有课程
    2 选择课程
    3 查看已选择的课程
    #反射的简单使用
    l = ['a','b','c']
    for num,i in enumerate(l,1):
        print(num,i)
    
    class A:
        def __init__(self,name,age):
            self.name = name
            self.age = age
    
    a = A('alex',18)
    a.name = 'alex'
    getattr(a,'name')
    setattr(a,'name','alex_SB')
    print(a.name)
    print(a.__dict__)
    del a.name
    print(a.__dict__)
    delattr(a,'age')
    print(a.__dict__)
    
    #执行结果:
    1 a
    2 b
    3 c
    alex_SB
    {'name': 'alex_SB', 'age': 18}
    {'age': 18}
    {}










  • 相关阅读:
    最新28个很棒的 jQuery 教程
    NetBeans 为PHP添加调试功能
    HTML5 存储API介绍
    PHP 变量判断
    jquery 与其它js 框架的解决办法
    从按下电源开关到bash提示符
    tar、gzip、unzip命令的详细使用方法
    Top命令中Load Average的含义
    Linux(BASH)命令搜索机制
    分析df和du的区别
  • 原文地址:https://www.cnblogs.com/skydragon/p/11681518.html
Copyright © 2011-2022 走看看