什么是反射?

用字符串数据类型的变量名来访问这个变量的值
反射的方法:getattr,hasattr,setattr,delattr
:(通过类名反射类名空间里面的内容的)
类:静态属性,类方法,静态方法
命名空间.xxx = gettattr(命名空间,“xxx”)
引子

class Student:def __init__(self): passdef cheak_course(self):print("cheak_course")def choose_course(self):print("choose_course")def choosed_course(self):print("查看已选的课程")stu = Student()
num = input(">>>>")
if num == "cheak_course":stu.cheak_course()
elif num == "choose_course":stu.choose_course()
elif num == "choosed_course":stu.choosed_course()

如果类的方法越多,下面的判断就越多,代码太冗余。可以使用反射
怎么通过用户输入的字符串拿到对应的值?

class Student:ROLE = "STUDENT"  # 静态属性@classmethoddef cheak_course(cls):  # 类方法print("查看课程")@staticmethoddef login():  # 静态方法print("登录")# 反射查看属性
print(Student.ROLE)
# 用户输入input进来的永远是字符串"ROLE",那么怎么从Student里面拿到ROLE呢
# eval 这个东西,要明确的写在代码里面的,不能用户输入什么就eval()什么,太不安全
print(getattr(Student, "ROLE"))  # 第一个参数的命名空间中的,变量名为第二个参数的值。前面是命名空间,后面是变量名,字符串# 反射调用方法
getattr(Student, "cheak_course")()# 反射调用静态方法
getattr(Student, "login")()# 结果
# STUDENT
# STUDENT
# 查看课程
# 登录

接收用户的输入的字符串

class Student:ROLE = "STUDENT"  # 静态属性@classmethoddef cheak_course(cls):  # 类方法print("查看课程")@staticmethoddef login():  # 静态方法print("登录")num = input("请输入要操作的动作:")
getattr(Student, num)()     #加括号就调用


这样就保证程序的绝对安全了,有这个方法就直接执行,没有的话就报错
如果要做的好一点,可以用hasattr,有这个方法的话就返回True,没有的话就返回False

class Student:ROLE = "STUDENT"  # 静态属性@classmethoddef cheak_course(cls):  # 类方法print("查看课程")@staticmethoddef login():  # 静态方法print("登录")num = input("请输入要操作的动作:")
if hasattr(Student, num):  # 输入的字符串在Student里面找到就返回True,找不到就返回Falsegetattr(Student, num)()

对象

反射方法,对象属性

class A():age = 100  # 静态属性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

模块

反射和直接调用效果是一样的

print(os.rename)  # 获取函数的内存地址
print(getattr(os, "rename"))
# 结果
# <built-in function rename>
# <built-in function rename>

反射别的模块中的内容

import osos.rename("__init__.py", "init")
# getattr(os, "rename")  就相当于os.rename   (没有括号)
getattr(os, "rename")('init', "__init__.py")  # 后面括号是参数
# 将文件名改回来再改回去

反射自己模块中的内容,找到自己当前文件的命名空间

#因为现在只能拿到字符串类型的数据,不知道模块名。要反射的话必须要有反射名
def wahaha():print("wahaha")def qqxing():print("qqixng")import sys# print(sys.modules)  # sys.modules表示所有在这个python程序中导入的模块
# 找到自己当前文件的命名空间
# print(sys.modules["__main__"])
# 结果:
# <module '__main__' from 'D:/参考/daydayup/day20/反射.py'>my_file = sys.modules["__main__"]
# my_file.wahaha()getattr(my_file, "wahaha")()
#结果
#wahaha

总结:

反射
getattr,hasattr
类名.名字
getattr(对象,“名字”)

对象名.名字
getattr(对象,“名字”)
模块名.名字
import 模块
getattr(模块,“名字”)

自己文件.名字
import sys
getattr(sys.modules[“
main”],“名字”)

反射演练

class Manager:def __init__(self, name):self.name = namedef create_student(self):print("创建学生账号")def create_course(self):print("创建课程")def ckeck_student_info(self):print("查看学生信息")class Student:def __init__(self, name):self.name = namedef cheak_course(self):print("cheak_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\n",strip()去掉换行符if user == username and pwd == password:  # 判断输入法的用户名密码,是否和存的用户名密码对上print("登录成功")return username, ident  # 返回用户名,身份,知道具体是谁import sysdef main():# 程序的逻辑在main里面usr, id = login()  # 拿到用户名和身份,身份就是Student或Manager,刚好和上面的类名一样print("use,id", usr, id)  # 返回的是两个字符串file = sys.modules["__main__"]  # 获取当前所在的模块,就是当前文件的命名空间cls = getattr(file, id)  # getattr(当前文件,Manager),从当前文件,找类Manager或Student的内存空间,id是从文件里拿的字符串,这样就能找到类名空间obj = cls(usr)  # 这个是实例化,拿到的就是对象print(Student, Manager)print(cls)  # 就是Manager类的内存地址main()


插播enumerate

l = ["a", "b", "c"]
for i in l:print(i)
# 结果
# a
# b
# c

1

l = ["a", "b", "c"]
for i in enumerate(l):print(i)
# 结果
# (0, 'a')
# (1, 'b')
# (2, 'c')

原地解包1

l = ["a", "b", "c"]
for num, i in enumerate(l):  # 从0开始print(num, i)
# 结果
# 0 a
# 1 b
# 2 c

原地解包2

l = ["a", "b", "c"]
for num, i in enumerate(l,1):  # 从1开始print(num, i)
#结果
# 1 a
# 2 b
# 3 c

主程序的逻辑不需要动,尽管添加学生和老师的方法就行。

class Manager:OPERATE_LIST = [("创造学生账号", "create_student"),("创建课程", "create_course"),("查看学生信息", "ckeck_student_info")]def __init__(self, name):self.name = namedef create_student(self):print("创建学生账号")def create_course(self):print("创建课程")def ckeck_student_info(self):print("查看学生信息")class Student:OPERATE_DIC = [('查看所有课程', 'check_course'),('选择课程', 'choose_course'),('查看已选择的课程', 'choosed_course')]def __init__(self, name):self.name = namedef cheak_course(self):print("cheak_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\n",strip()去掉换行符if user == username and pwd == password:  # 判断输入法的用户名密码,是否和存的用户名密码对上print("登录成功")return username, ident  # 返回用户名,身份,知道具体是谁import sysdef main():# 程序的逻辑在main里面usr, id = login()  # 拿到用户名和身份,身份就是Student或Manager,刚好和上面的类名一样print("use,id", usr, id)  # 返回的是两个字符串file = sys.modules["__main__"]  # 获取当前所在的模块,就是当前文件的命名空间cls = getattr(file, id)  # getattr(当前文件,Manager),从当前文件,找类Manager或Student的内存空间,id是从文件里拿的字符串,这样就能找到类名空间obj = cls(usr)  # 这个是实例化,拿到的就是对象operate_list = cls.OPERATE_LIST  # 通过类名拿静态变量while True:  # 循环起来for num, i in enumerate(operate_list,1):  # 1 ('创造学生账号', 'create_student')   2 ('创建课程', 'create_course')  3 ('查看学生信息', 'ckeck_student_info')print(num, i[0])  # 1 创造学生账号2 创建课程3 查看学生信息choise = int(input("请输入要操作的序号:"))  # 拿到用户要操作的序号,转成证书类型choice_item = operate_list[choise - 1]  # 需要从1开始的,是("创造学生账号", "create_student")这样的元组getattr(obj, choice_item[1])()  # choice_item[1]这个就是要找的字符串main()
#结果:
# user: Alex
# pwd: 123456
# 登录成功
# use,id Alex Manager
# 1 创造学生账号
# 2 创建课程
# 3 查看学生信息
# 请输入要操作的序号:1
# 创建学生账号
# 1 创造学生账号
# 2 创建课程
# 3 查看学生信息
# 请输入要操作的序号:2
# 创建课程
# 1 创造学生账号
# 2 创建课程
# 3 查看学生信息
# 请输入要操作的序号:3
# 查看学生信息
# 1 创造学生账号
# 2 创建课程
# 3 查看学生信息
# 请输入要操作的序号:

setattr 修改(了解)

class A:def __init__(self, name):self.name = namea = A("alex")
# a.name = "alex_SB"  # 一般正常这样用
# getattr(a,"name")   #取值
setattr(a, "name", "alex_SB")  # 修改,最后一个是修改后的数据
print(a.name)
# 结果
# alex_SB

delatter删除(了解)

不用反射

class A:def __init__(self, name):self.name = namea = A("alex")
print(a.__dict__)
del a.name
print(a.__dict__)# 结果
# {'name': 'alex'}
# {}

用反射

class A:def __init__(self, name):self.name = namea = A("alex")
print(a.__dict__)
delattr(a,"name")
print(a.__dict__)# 结果
# {'name': 'alex'}
# {}

反射---getattr,hasattr,setattr,delattr加插播enumerate相关推荐

  1. Python自动化运维之13、异常处理及反射(__import__,getattr,hasattr,setattr)

    一.异常处理 python异常: python的运行时错误称作异常 (1)语法错误:软件的结构上有错误而导致不能被解释器解释或不能被编译器编译 (2)逻辑错误:由于不完整或不合法的输入所致,也可能是逻 ...

  2. Python面向对象:反射(hasattr和getattr和setattr和delattr)

    一.反射在类中的使用 反射就是通过字符串来操作类或者对象的属性 反射本质就是在使用内置函数,其中反射有以下四个内置函数: hasattr:判断一个方法是否存在与这个类中 getattr:根据字符串去获 ...

  3. python--基础知识点--反射机制——hasattr、getattr、setattr、delattr

    一.概念 反射:可以把字符串映射到实例的变量或者实例的方法然后可以去执行调用.修改等操作. getattr :获取指定字符串名称的对象属性或方法. setattr :为对象设置一个对象属性或方法. h ...

  4. python hasattr()、getattr()、setattr()、delattr()函数

    Python hasattr().getattr().setattr().delattr()函数 hasattr()函数 hasattr()函数用于判断是否包含对应的属性:当然,对于Python的对象 ...

  5. python中attr_python中hasattr()、getattr()、setattr()函数的使用

    引言: 在阅读高手写的代码时,有很多简写的形式,如果没有见过还真的看不太懂是什么意思,其中一个比较常用的就是getattr()用来调用一个类中的变量或者方法,相关联的hasattr().getattr ...

  6. python中hasattr()、getattr()、setattr()函数的使用

    在阅读高手写的代码时,有很多简写的形式,如果没有见过还真的看不太懂是什么意思,其中一个比较常用的就是getattr()用来调用一个类中的变量或者方法,相关联的hasattr().getattr().s ...

  7. python hasattr函数_Python3 hasattr()、getattr()、setattr()函数简介

    Python3 hasattr().getattr().setattr()函数简介 一.hasattr(object, name) 判断object对象中是否存在name属性,当然对于python的对 ...

  8. Python学习: hasattr()、getattr()、setattr()函数简介

    一.hasattr(object, name) 判断object对象中是否存在name属性,当然对于python的对象而言,属性包含变量和方法:有则返回True,没有则返回False:需要注意的是na ...

  9. python中setattr用法_python中hasattr()、getattr()、setattr()函数的使用

    引言: 在阅读源码时,有很多简写的形式,其中一个比较常用的就是getattr()用来调用一个类中的变量或者方法,相关联的hasattr().getattr().setattr()函数的使用也一并学习了 ...

最新文章

  1. 小米语音首席科学家Daniel Povey:下一代Kaldi将走向何方?
  2. python32位安装
  3. python源码提取_Python|第一个python程序(获取音乐下载地址,附源码)
  4. java发生fullgc的时机_2021-01-02:java中,MinorGC、MajorGC、FullGC 什么时候发生?
  5. Office - 安装程序找不到office.zh-cn\*.文件
  6. MinGW编译boost库
  7. Django自带的用户验证与事务管理的基本概念理解
  8. 2017.4.2 loli测试
  9. 关于三段式状态机第三段是组合逻辑还是时序逻辑的问题?
  10. 服务器主板维修教学视频,第60讲 超微服务器主板远程管理讲解与演示
  11. 遇到svn is already locked 解决办法
  12. RRU原理详解以及eCPRI+Low-Phy(一篇文章让你搞懂RRU---呕心沥血之作)
  13. 基于MFC开发的单文档画图(线段,多线段,矩形,椭圆,多边形),选中,变色,平移,线段长度,区域面积计算
  14. HCL 模拟器安装注意
  15. 线程、多线程与线程池总结
  16. flutter获取图片大小的Widget(网络图片大小,本地图片大小)
  17. 关于stm32f4xx的片上外设I2C模块用作主模式下BUSY位总是置1的解决方法
  18. [3] Jenkins 系列:如何获取触发Jenkins Job的用户信息?
  19. 【LeetCode】第930题——和相同的二元子数组(难度:中等)
  20. doug lea java并发_Doug Lea

热门文章

  1. Debian系统中字体发虚的处理方法
  2. 浙江计算机在职研究生学费多少钱,浙江大学在职研究生2018年学费是多少?
  3. 解决G13无法刷机的问题。
  4. Matlab:实现“光学拍”仿真
  5. 在Virtualbox中的Ubuntu虚拟机中,安装Guest Additions客户端增强包时出错
  6. POJ 3579 二分
  7. [对比]Android的差异设计和iOS的统一设计规范
  8. android接入支持海外的支付,visa,mastercard
  9. 在.sln文件中设置Visual Studio默认启动项目的简单方法
  10. 计算机网络复习——第三章数据链路层