反射

1.两个内置函数:

  issubclass(Son,Foo)    判断Son是否是Foo的子类  

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

class Foo(object):pass
class Son(Foo):pass
ret = issubclass(Son,Foo)
print(ret)   #True

  isinstance(obj,cls)       判断对象与类之间的关系,这个类也包括父类

a = 1
ret1 = type(a) is int
ret2 = isinstance(a,int)
print(ret1)   #True
print(ret2)   #True
class User(object):pass
class VIPUser(User):pass

alex = VIPUser()
ret1 = type(alex) is User
ret2 = isinstance(alex,User)
print(ret1,ret2)   #False True
ret1 = type(alex) is VIPUser
ret2 = isinstance(alex,VIPUser)
print(ret1,ret2)   #True True

isinstance(obj,类)

    承认继承关系的

类 = type(obj)

    只承认实例化这个对象的那个类(不承认所有的继承关系)

 

反射

 

用"字符串"类型的属性名/方法名来找到属性的值或者方法的内存地址

所有可以反射的内容实际上都是变量  有内存地址

内存地址存的是"具体的值",直接能取到结果

内存地址存的是"函数\方法\类",取到的是内存地址

函数、类、类中的各种方法 一打印打印出的是地址

# hasattr和getattr
    # 只要是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这种结构
        # 直接调用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 只用来修改或者添加属性\变量,不能用来处理函数或者是其他方法
    # a.b = value
    # setattr(a,'b',value)
    
# delattr 只用来删除 属性\变量
    # del a.b 删除属性  相当于删除了a对象当中的b属性
    # delattr(a,'b')

 

# 如何反射类
class Foo:pass
import sys
clas = getattr(sys.modules[__name__],'Foo')
print(clas)   # == Foo
obj = clas()   # Foo() 相当于实例化一个Foo对象的过程
# 如何反射函数
def func():print('12345')
import sys
func_addr = getattr(sys.modules[__name__],'func')
func_addr() # func()
# 如何反射变量
# 全局变量
a = {2,2,3}
import sys
b = getattr(sys.modules[__name__],'a')
print(b)

如何反射类里的成员

     类中的成员 : 静态变量 静态方法 类方法 对象方法 property方法

     习惯使用类调用的有哪些 : 静态变量 静态方法 类方法

     对象中的成员 : 对象属性

     习惯使用对象调用的有哪些:对象属性 对象方法 property方法

     类和对象中成员的反射 都是遵循"调用习惯"的

class Foo:
    Country = 'China'

    @classmethod
    def showCountry(cls):
        print('in showCountry',cls.Country)

    @staticmethod
    def wahaha():
        print('wahaha')
# 类中的静态属性
print(getattr(Foo,'Country'))  #

# 类中的类方法
print(getattr(Foo, 'showCountry'))   # Foo.showCountry  (内存地址)
getattr(Foo, 'showCountry')()   # Foo.showCountry()

# 类中的静态方法
getattr(Foo, 'wahaha')()   # Foo.wahaha()
class Student:
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def eat(self):
        print(self.name + ' is eating')

alex = Student('alex',84)
print(getattr(alex,'name'))   # alex.name
print(getattr(alex,'age'))   # alex.age
getattr(alex,'eat')()    # alex.eat()

反射模块中的方法

import re
ret = re.findall('\d+','2985urowhn0857023u9t4')
print(ret)  #['2985', '0857023', '9', '4']
# 'findall'
getattr(re,'findall')   # re.findall
ret = getattr(re,'findall')('\d','wuhfa0y80aujeiagu')
print(ret)  #['0', '8', '0']
import time
# 'time'
now  = getattr(time,'time')()
print(now)   #1554189223.6731317

time.sleep(1)
print(321)
getattr(time,'sleep')(1)   # time.sleep(1)
print(123)

反射本文件中的内容 :只要是出现在全局变量中的名字都可以通过getattr(modules[__name__],字符串数据类型的名字)

class Manager:   # 管理员用户
    opt_lst = ['创建课程','给学生创建账号','查看所有课程','查看所有学生','查看所有学生的选课情况','退出']
    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')

    def show_students_courses(self): # 查看所有学生的选课情况
        print('in Manager show_students_courses')

    def quit(self):
        exit()

#

class Student:
    opt_lst = ['查看所有课程','选择课程' ,'查看已选课程', '退出']
    def __init__(self,name):
        self.name  = name

    def show_courses(self):  # 查看所有课程
        print('in Student show_courses')

    def choose_course(self):         # 选择课程
        print('in Student choose_course')
        
    def show_selected_course(self):  # 查看已选课程
        print('in Student show_selected_course')

    def quit(self):
        exit()

# 1.输入用户名和密码
# 2.程序判断 用户名密码 是否正确   获知身份
# 3.如果是学生
    # 1,2,3,4学生能做的事情
    # 让用户选择
# 4.如果是管理员
    # 1,2,3,4,5,6管理员能做的事
    # 让管理员选择
import hashlib
def get_md5(usr,pwd):
    md5 = hashlib.md5(usr.encode('utf-8'))
    md5.update(pwd.encode('utf-8'))
    return md5.hexdigest()

def login(usr,pwd):
    with open('userinfo',encoding='utf-8') as f:
        for line in f:
            username,password,ident = line.strip().split('|')
            if usr == username and get_md5(usr,pwd) == password:
                return {'result':True,'identify':ident,'username':usr}
        else: return {'result':False}

def auth():
    opt_lst1 = ['登录','退出']
    while True:
        for index,opt in enumerate(opt_lst1,1):
            print(index,opt)
        num = int(input('请输入你要做的操作 :'))
        if num == 1:
            usr = input('username :')
            pwd = input('password :')
            ret = login(usr,pwd)
            if ret['result']:
                print('登录成功')
                return ret
            else:
                print('登录失败')
        elif num == 2:
            exit()


ret = auth()
print(ret)
if ret['result']:
    if ret['identify'] == 'Manager':
        manager = Manager(ret['username'])
        while True:
            for index,opt in enumerate(Manager.opt_lst,1):
                print(index,opt)
            num = int(input('请选择您要操作的序号 :'))
            if num == 1:
                manager.create_course()
            elif num == 2:
                manager.create_student()
            elif num == 3:
                manager.show_courses()
            elif num == 4:
                manager.show_students()
            elif num == 5:
                manager.show_students_courses()
            elif num == 6:
                manager.quit()
    elif ret['identify'] == 'Student':
        student = Student(ret['username'])
        while True:
            for index,opt in enumerate(Student.opt_lst,1):
                print(index,opt)
            num = int(input('请选择您要操作的序号 :'))
            if num == 1:
                student.show_courses()
            elif num == 2:
                student.show_selected_course()
            elif num == 3:
                student.choose_course()
            elif num == 4:
                student.quit()
不使用反射完成的选课系统
class Manager:   # 管理员用户
    opt_lst = [('创建课程','create_course'),('给学生创建账号','create_student'),
               ('查看所有课程','show_courses'),('查看所有学生','show_students'),
               ('查看所有学生的选课情况','show_students_courses'),('退出','quit')]
    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')

    def show_students_courses(self): # 查看所有学生的选课情况
        print('in Manager show_students_courses')

    def quit(self):
        exit()

class Student:
    opt_lst = [('查看所有课程','show_courses'), ('查看已选课程','show_selected_course'),
               ('选择课程','choose_course'), ('退出','quit')]
    def __init__(self,name):
        self.name  = name

    def show_courses(self):  # 查看所有课程
        print('in Student show_courses')

    def show_selected_course(self):  # 查看已选课程
        print('in Student show_selected_course')

    def choose_course(self):         # 选择课程
        print('in Student choose_course')

    def quit(self):
        exit()

# 1.输入用户名和密码
# 2.程序判断 用户名密码 是否正确   获知身份
# 3.如果是学生
    # 1,2,3,4学生能做的事情
    # 让用户选择
# 4.如果是管理员
    # 1,2,3,4,5,6管理员能做的事
    # 让管理员选择
import hashlib
def get_md5(usr,pwd):
    md5 = hashlib.md5(usr.encode('utf-8'))
    md5.update(pwd.encode('utf-8'))
    return md5.hexdigest()

def login(usr,pwd):
    with open('userinfo',encoding='utf-8') as f:
        for line in f:
            username,password,ident = line.strip().split('|')
            if usr == username and get_md5(usr,pwd) == password:
                return {'result':True,'identify':ident,'username':usr}
        else: return {'result':False}

def auth():
    opt_lst1 = ['登录','退出']
    while True:
        for index,opt in enumerate(opt_lst1,1):
            print(index,opt)
        num = int(input('请输入你要做的操作 :'))
        if num == 1:
            usr = input('username :')
            pwd = input('password :')
            ret = login(usr,pwd)
            if ret['result']:
                print('登录成功')
                return ret
            else:
                print('登录失败')
        elif num == 2:
            exit()

import sys
ret = auth()
print(ret)
if ret['result']:
    if hasattr(sys.modules[__name__],ret['identify']):
        # sys.modules[__name__]表示找到的当前文件所在的内存空间
        # ret['identify']只能是'Manager','Student'
        # hasattr(sys.modules[__name__],ret['identify'])判断当前的空间中有没有Student或者Manager这个名字
        cls = getattr(sys.modules[__name__],ret['identify'])
        obj = cls(ret['username'])
        # cls 要么 == Student类的内存地址,要么 == Manager类的内存地址
        while True:
            for index,opt in enumerate(cls.opt_lst,1):
                print(index,opt[0])
            num = int(input('请选择您要操作的序号 :'))
            if hasattr(obj,cls.opt_lst[num-1][1]):
                getattr(obj,cls.opt_lst[num-1][1])()
    # if ret['identify'] == 'Manager':
    #     manager = Manager(ret['username'])
    #     while True:
    #         for index,opt in enumerate(Manager.opt_lst,1):
    #             print(index,opt[0])
    #         num = int(input('请选择您要操作的序号 :'))
    #         if hasattr(manager,Manager.opt_lst[num-1][1]):
    #             getattr(manager,Manager.opt_lst[num-1][1])()
    # elif ret['identify'] == 'Student':
    #     student = Student(ret['username'])
    #     while True:
    #         for index,opt in enumerate(Student.opt_lst,1):
    #             print(index,opt[0])
    #         num = int(input('请选择您要操作的序号 :'))
    #         if hasattr(student,Student.opt_lst[num-1][1]):
    #             getattr(student,Student.opt_lst[num-1][1])()
使用反射完成选课系统

 

posted @ 2019-04-02 15:20  Xiao_Xu  阅读(103)  评论(0编辑  收藏  举报