反射---getattr,hasattr,setattr,delattr加插播enumerate

什么是反射?

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

class Student:
    def __init__(self): pass

    def 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"  # 静态属性

    @classmethod
    def cheak_course(cls):  # 类方法
        print("查看课程")

    @staticmethod
    def 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"  # 静态属性

    @classmethod
    def cheak_course(cls):  # 类方法
        print("查看课程")

    @staticmethod
    def login():  # 静态方法
        print("登录")


num = input("请输入要操作的动作:")
getattr(Student, num)()		#加括号就调用

在这里插入图片描述
在这里插入图片描述

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

class Student:
    ROLE = "STUDENT"  # 静态属性

    @classmethod
    def cheak_course(cls):  # 类方法
        print("查看课程")

    @staticmethod
    def login():  # 静态方法
        print("登录")


num = input("请输入要操作的动作:")
if hasattr(Student, num):  # 输入的字符串在Student里面找到就返回True,找不到就返回False
    getattr(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 os

os.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”],“名字”)

反射演练

选课系统
login
判断人的身份
判断身份,根据身份实例化
根据每个身份对应的类,让用户选择能够做的事

class Manager:
    def __init__(self, name):
        self.name = name

    def create_student(self):
        print("创建学生账号")

    def create_course(self):
        print("创建课程")

    def ckeck_student_info(self):
        print("查看学生信息")


class Student:
    def __init__(self, name):
        self.name = name

    def 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 sys


def 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 = name

    def 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 = name

    def 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 sys


def 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 = name


a = 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 = name


a = A("alex")
print(a.__dict__)
del a.name
print(a.__dict__)


# 结果
# {'name': 'alex'}
# {}

用反射

class A:
    def __init__(self, name):
        self.name = name


a = A("alex")
print(a.__dict__)
delattr(a,"name")
print(a.__dict__)

# 结果
# {'name': 'alex'}
# {}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/28895.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【python】flask+pymysql 实现Web端操作数据库!

Flask是一个使用 Python 编写的轻量级 Web 应用框架。其 WSGI 工具箱采用 Werkzeug &#xff0c;模板引擎则使用 Jinja2 。Flask使用 BSD 授权。 Flask也被称为 “microframework” &#xff0c;因为它使用简单的核心&#xff0c;用 extension 增加其他功能。Flask没有默认使用…

Qt5.15.10+msvc2019_x86+qwebengine(含mp4)源码编译

系统要求: win10 64bit 英文版(或者把“区域”->“管理”->“非Unicode程序中所使用的当前语言”->改为"英语(美国)") 内存16g够用,cpu性能越高越好,硬盘在安装环境、下载源码后,至少还有100g可用空间 下载源码: https://download.qt.io/archiv…

大话设计模式之——单例模式

单例&#xff08;Singleton&#xff09; Intent 确保一个类只有一个实例&#xff0c;并提供该实例的全局访问点。 Class Diagram 使用一个私有构造函数、一个私有静态变量以及一个公有静态函数来实现。 私有构造函数保证了不能通过构造函数来创建对象实例&#xff0c;只能…

Python零基础入门(二)——IDE介绍以及Python+PyCharm的安装

系列文章目录 个人简介&#xff1a;机电专业在读研究生&#xff0c;CSDN内容合伙人&#xff0c;博主个人首页 Python入门专栏&#xff1a;《Python入门》欢迎阅读&#xff0c;一起进步&#xff01;&#x1f31f;&#x1f31f;&#x1f31f; 码字不易&#xff0c;如果觉得文章不…

路径规划算法:基于适应度相关优化的路径规划算法- 附代码

路径规划算法&#xff1a;基于适应度相关优化的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于适应度相关优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用智能…

Unity基础4——LineRenderer

一、参数面板 二、参数介绍 Loop&#xff1a;是否首尾相连 Positions&#xff1a;线段的点 Width&#xff1a;线段宽度曲线的调整 Color&#xff1a;颜色变化 需要搭配材质才有效果 Corner Vertices&#xff1a;角顶点、圆角 此属性指&#xff0c;在一条线中绘制角时使用了…

一文读懂功率信号源(信号发生器)

功率信号源是一种用于产生高功率信号的电子设备&#xff0c;它广泛应用于各个领域&#xff0c;在生产、测试和调试中起着重要的作用。下面就让安泰将介绍功率信号源的基本概念、工作原理、分类以及应用。 功率信号源是一种能够产生稳定输出功率的设备。它通常由一个稳压电源和一…

红帽认证常见答疑(二):电脑配置、实验环境和考试环境、可以自学吗

学习红帽需要配置什么样的电脑&#xff1f; RHCE推荐学员自己的电脑内存在16G左右&#xff0c;RHCA推荐学员电脑内存在32-64G&#xff0c;且最好配置128G以上的固态硬盘&#xff0c;如果自己没有该配置的电脑&#xff0c;誉天可以提供远程学习环境&#xff0c;可以随时随地连接…

Java实现的五子棋游戏 ~java.awtjava.swing

文章目录 Java实现的五子棋游戏1.实现效果2.实现源码2.1运行主函数main.java2.2 棋盘布局Chessboard.java3.Algorithm算法 点击下载链接&#xff1a;Java实现的五子棋游戏源码下载 Java实现的五子棋游戏 作业要求&#xff1a; &#xff08;1&#xff09;课题代号&#xff1a; …

【裸机开发】使用汇编清除 .bss 段

目录 1、为什么要清除 .bss 段 2、使用汇编清除 .bss 段 1、为什么要清除 .bss 段 .bss 段保存的是 未被初始化 或者 初始化为0 的全局/静态变量。在编译器看来&#xff0c;这些东西是多余的&#xff0c;实际并不会给他们分配空间。因此&#xff0c;编译生成目标文件的时候&…

提升安全性与合规性的关键工具ADAudit Plus

在当今数字化时代&#xff0c;企业对于安全性和合规性的要求越来越高。特别是在Active Directory&#xff08;AD&#xff09;域中&#xff0c;作为组织的核心身份验证和访问管理系统&#xff0c;审计活动的重要性变得前所未有。为了满足这一需求&#xff0c;ADAudit Plus成为了…

A Survey of Large Language Models

本文是LLM系列的第一篇文章&#xff0c;针对《A Survey of Large Language Models》的翻译。 大语言模型综述 摘要1 引言2 概述2.1 LLM的背景2.2 GPT系列模型 的技术演化 3 LLMs的资源3.1 公开可用的模型检查点或APIs3.2 常用的语料库3.3 库资源 4 预训练4.1 数据收集4.1.1 数…

深入剖析 Python 函数参数传递机制及高级应用

前言 在本篇文章中&#xff0c;笔者将带你深入探讨 Python 函数传参的进阶主题。 通过阅读本篇文章&#xff0c;你可以深入了解 Python 函数传参的进阶主题&#xff0c;掌握更多高级的函数技巧&#xff0c;提升你的 Python 编程能力。 前面分享了Python 函数传参基础篇&#xf…

嵌入式Linux应用开发笔记:串口

文章目录 目的基础说明开发准备设备树应用程序 应用程序与演示代码演示 总结设备树文件 目的 串口&#xff08;UART&#xff09;是嵌入式设备中比较常用的功能。这篇文章将记录下应用程序中串口操作相关内容。 这篇文章中内容均在下面的开发板上进行测试&#xff1a; 《新唐N…

中介者模式(二十一)

相信自己&#xff0c;请一定要相信自己 上一章简单介绍了观察者模式(二十), 如果没有看过, 请观看上一章 一. 中介者模式 引用 菜鸟教程里面中介者模式介绍: https://www.runoob.com/design-pattern/mediator-pattern.html 中介者模式&#xff08;Mediator Pattern&#xff…

Django-带参数的路由编写(一)【不用正则表达式匹配的简单带参数路由】

在某urls.py文件有如下的路由配置语句&#xff1a; urlpatterns [path(app2/show/<int:id>/,views.show_id), ]语句&#xff1a; path(app2/show/<int:id>/,views.show_id),中的<int:id>就是带参数的URL中的参数部分&#xff0c;其语法格式如下&#xff1a…

Vue中如何进行图片识别与物体检测

Vue中如何进行图片识别与物体检测 随着人工智能技术的发展&#xff0c;图像识别和物体检测已经成为了很多应用场景的必备功能。在Vue中如何使用百度AI或腾讯AI等云服务实现图片识别和物体检测呢&#xff1f;本文将为您介绍一些基本概念和示例代码&#xff0c;帮助您快速入门。…

【数据库】Mysql索引、事务与存储引擎

文章目录 一、索引介绍1. 索引的概念2. 索引的作用与副作用2.1 索引的作用2.2 索引的副作用2.3 如何实现索引 3. 创建索引的原则依据4. 索引的分类和创建4.1 普通索引直接创建索引修改表方式创建创建表的时指定索引 4.2 唯一索引直接创建唯一索引修改表方式创建创建表的时候指定…

两个HC-05蓝牙之间的配对

两个HC-05蓝牙之间的配对 文章目录 两个HC-05蓝牙之间的配对1.进入AT指令模式后&#xff0c;先确定是否为AT模式&#xff1a;2.获取模块A,B的地址3.将蓝牙A配置为主模式&#xff0c;将蓝牙B配置为从模式&#xff1a;4.设置模块通信波特率,蓝牙模块A和B的配置需要相同6.验证 买了…

间接采购管理中常见的五大挑战

间接采购&#xff0c;有时也被称为间接费用或尾部支出&#xff0c;这些商品或服务不是制造产品直接必需的&#xff0c;而是日常运营所需的。 ● 办公室和行政用品 ● 商店地点的消耗品&#xff08;例如&#xff0c;清洁用品&#xff09; ● 设施管理费用 ● 专业服务 ● 旅行…