2019-04-01-day023-对象实例的反射实例化

学习方法

  • 学练改管测
    • 听别人说 读 input
    • 自己说 自己写 output
  • 解决语法错误
  • 解决逻辑错误
    ##内容回顾
    ##继承 多态 封装
  • property
  • classmethod
  • staticmethod
    ##封装
  • 面向对象的语言本身就具有封装的特性 : 属性和方法都放在它所属的类中
  • 私有化 :
    • __名字
      • 静态属性\对象属性
      • 方法
        • 私有的方法
        • 私有的类方法
        • 私有的静态方法
    • 如何实现的
      • 通过在类的内部定义或者使用的时候会自动添加_类名来进行变形
      • 在类的外部使用的时候由于python不会做自动的变形,所以这个属性就被隐藏了
      • 如果我们一定要在外部使用,也可以自己加上_类名的变形机制
      • 但十分不建议你在类的外部直接使用私有的名字
    • 私有的
      • 不能在类的外部使用
      • 也不能被继承
class A:
    @classmethod
    def __func(cls):
        print('infunc')

    @classmethod
    def f(cls):
        cls.__func()
print(A.f)
class A:
    @staticmethod
    def __func():
        print('infunc')

    @classmethod
    def f(cls):
        cls.__func()

A.f()

property 把一个方法变成一个属性

class Circle:
  @property
  def area(self):
      pass

c.area()
c.area          # get 获取某个值
c.area = 1      # set 给某一个属性赋值
del c.area      # delete 删某个属性
class Box:   # 盒子
    def __init__(self,length,width,height):
        self.__len = length
        self.__width = width
        self.__height = height

    @property
    def len(self):
        return self.__len

    @len.setter
    def len(self,value):
        if type(value) is int or type(value) is float:
            self.__len = value

    @len.deleter
    def len(self):
        del self.__len


盒子 = Box(10,20,30)
ret = 盒子.len
print(ret)

盒子.len = 'aaaa'
ret = 盒子.len
print(ret)

del 盒子.len
  1. 基础的方法和语法能不能记住 :
    • 基础的数据类型 函数(内置函数\匿名函数的语法\普通函数)
    • 面向对象的基础语法 定义类 实例化 对象使用方法 查看属性
    • 继承的语法 多态的概念 封装的语法
    • 几个装饰器 :对应的功能,方法长什么样
  2. 基础的需求能不能完成
  3. 进阶的知识点 : 装饰器 生成器 递归函数 各种知识点的活学活用
class File:   # 盒子
    def __init__(self,path):
        self.__path = path

    @property
    def f(self):
        self.__f = open(self.__path,mode='w',encoding='utf-8')
        return self.__f

    @f.deleter
    def f(self):
        self.__f.close()
        del self.__f


obj = File()
obj.f # 文件句柄
obj.f.write('balabala')
del obj.f
classmethod
class A:
    @classmethod
    def func(cls):
        cls.静态属性名
        cls.静态方法
        cls.类方法


class A:
    @staticmethod
    def func():
        pass

今日内容

  1. 面向对象结束
  2. logging模块 + 异常处理
  3. 模块和包 + 考试
  4. 模块和包 + 软件开发规范
  5. 网络编程 4天
  6. 并发编程 6天

今日内容

  • 反射
    • 反射对象中的内容
    • 反射类中的内容
    • 反射本文件中的内容
    • 反射模块中的内容
  • 内置方法
    • 能学多少学多少

issubclass

issubclass(Son,Foo)

  • 判断Son是否是Foo的子类
  • 判断类与类之间是否有继承关系关系
class Foo(object):pass
class Son(Foo):pass
ret = issubclass(Son,Foo)
print(ret)

isinstance(obj,cls) #判断对象与类之间的关系,这个类也包括父类
type()
a = 1
ret1 = type(a) is int
ret2 = isinstance(a,int)
print(ret1)
print(ret2)

class User(object):pass
class VIPUser(User):pass

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

isinstance(obj,类)

  • 承认继承关系的

类 = type(obj)

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

反射

  • 知识点
    • 所有的a.b都可以变成getattr(a,'b')
    • 用字符串数据类型的变量名 来获取实际的变量值
    • 用字符串数据类型的变量名 找到这个变量对应的内存地址
  • 使用对象反射
    • obj.属性名
    • obj.方法名()
  • 使用类反射
    • cls.静态变量名
    • cls.类方法名()
    • cls.静态方法名()
  • 使用模块反射
import time
time.time()

#调用函数和方法 地址+()
def func():
    print(1)

func()
a = func
a()

#反射当前文件

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])()

如何使用反射

alex = Manager('alex')
print(alex.name)    # ==> print(getattr(alex,'name'))   用的相对少
funcname = 'create_course'
a = getattr(alex,funcname)
b = alex.create_course
print(a)
print(b)
getattr(alex,'create_course')()   # ==> # alex.create_course()   用的多
  • 两种方式
    • 对象名.属性名 / 对象名.方法名() 可以直接使用对象的方法和属性
    • 当我们只有字符串数据类型的内容的时候
      • getattr(对象名,'方法名')()
      • getattr(对象名,'属性名')
  • shop 买东西类
    • 浏览商品 scan_goods
    • 选择商品 ,添加到购物车 choose_goods
    • 删除商品 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)

使用类反射

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 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)
只要是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)

反射本文件中的内容 :

  • 只要是出现在全局变量中的名字都可以通过
getattr(modules[__name__],字符串数据类型的名字)
from sys import modules
print(modules)    # DICT KEY是模块的名字,value就是这个模块对应的文件地址

import re
print(re)   # <module 're' from 'D:\\python3\\lib\\re.py'>
print(modules['re'])
#选课系统
're': <module 're' from 'D:\\python3\\lib\\re.py'>
print(re.findall)
print(modules['re'].findall)
a = 1
b = 2
while True:
    name = input('变量名 :')
    print(__name__)
    print(getattr(modules[__name__],name))

'__main__': <module '__main__' from 'D:/PyCharmProject/s20/day23/5.反射.py'>
print(a,b)
print(modules['__main__'].a)
print(modules['__main__'].b)

print(getattr(modules['__main__'], 'a'))
print(getattr(modules['__main__'], 'b'))

语法

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这种结构
   # 直接调用func()
       # getattr(sys.modules[__name__],'func')()
   # 直接使用类名 Person()
       # getattr(sys.modules[__name__],'Person')()
   # 直接使用变量名 print(a)
       # getattr(sys.modules[__name__],'a')
所有的getattr都应该和hasattr一起使用
   # if hasattr():
        getattr()
'''
class A:
   def qqxing(self):
       print('qqxing')

alex = A()
alex.name = 'sb'
print(alex.name)

'name'
setattr 能够通过字符串数据类型的变量名 给一个对象创建一个新的属性
setattr(alex,'name','sb')   # alex.name = 'sb'
print(alex.name)

def wahaha(self):
    print('wahaha',self.name)

setattr(alex,'wahaha',wahaha)
print(alex.__dict__)
alex.wahaha(alex)

delattr()
print(alex.__dict__)
delattr(alex,'name')   # del alex.name
print(alex.__dict__)
'''
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 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 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()


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()



##登录 一个用户在一台电脑上只能登录三次,三次之后就锁住了
在函数里不能用print
   # 模块 写一个函数完成一个功能

使用反射完成的选课作业

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])()



登录 一个用户在一台电脑上只能登录三次,三次之后就锁住了
在函数里不能用print
   # 模块 写一个函数完成一个功能

猜你喜欢

转载自www.cnblogs.com/meilong/p/20190401day023.html