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

news2024/12/22 18:33:25

什么是反射?

用字符串数据类型的变量名来访问这个变量的值
反射的方法: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'}
# {}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue中如何进行代码高亮与语法着色?

Vue中如何进行代码高亮与语法着色&#xff1f; 在Vue的开发过程中&#xff0c;我们经常需要展示代码片段或者进行代码高亮与语法着色。Vue提供了多种方式来实现代码高亮与语法着色&#xff0c;本文将为你详细介绍这些方法。 1. 使用prism.js进行代码高亮与语法着色 prism.js是…

mybatis的一级缓存和二级缓存

目录 1、简介 2、Mybatis缓存 3、一级缓存 3.1、初体验测试 3.2、一级缓存失效的四种情况 4、二级缓存 4.1、使用步骤 4.2、结论 5、缓存原理 1、简介 什么是缓存 [ Cache ]&#xff1f; 存在内存中的临时数据。将用户经常查询的数据放在缓存&#xff08;内存&…

gomod在项目中的作用

Part1gomod在golang项目中的作用 1介绍 gomod是Go语言中一个非常重要的工具&#xff0c;它在Golang项目的开发过程中扮演着关键的角色。gomod是模块依赖管理工具&#xff0c;可以帮助开发者更好地管理和组织项目的依赖关系&#xff0c;提供了便捷的方式来管理和升级依赖项。 2为…

gtk实现spice剪切板

重要的函数&#xff1a; void spice_main_channel_clipboard_selection_grab(SpiceMainChannel *channel, guint selection, guint32 *types, int ntypes); 抓取剪切板 void spice_main_channel_clipboard_selection_release(SpiceMainChannel *channel, guint selection); 剪…

软件项目管理需要具备哪些能力?

作为一名软件项目管理者&#xff0c;在处理许多事情时需要不断提高个人在数据分析处理、项目业务流程管理等各个领域的能力。当然作为过来人&#xff0c;我也很清楚很多软件项目管理新人也较为疑惑如何提高自己的能力和专业水平&#xff0c;以便提高工作效率。那我也想与大家唠…

【论文阅读笔记】Local Model Poisoning Attacks to Byzantine-Robust Federated Learning

个人阅读笔记&#xff0c;如有错误欢迎指出&#xff01; 会议&#xff1a; Usenix 2020 [1911.11815] Local Model Poisoning Attacks to Byzantine-Robust Federated Learning (arxiv.org) 问题&#xff1a; 模型攻击对拜占庭鲁棒性联邦学习的攻击效果尚未清楚 创新点&…

SpringBatch从入门到实战(六):ItemReader

一&#xff1a;ListItemReader 用于简单的开发测试。 Bean public ItemReader<String> listItemReader() {return new ListItemReader<>(Arrays.asList("a", "b", "c")); }二&#xff1a;FlatFileItemReader 1.1 完全映射 当文件…

万物云原生下的服务进化 | 京东云技术团队

导读&#xff1a; 在万物云原生下的环境下&#xff0c;Java的市场份额也因耗资源、启动慢等缺点&#xff0c;导致在云原生环境里被放大而降低&#xff0c;通过这篇文章&#xff0c;读者可以更好地了解如何在云原生环境下通过升级相关版本和使用GraalVM打出原生镜像到方式&…

Linux之特殊权限

目录 Linux之特殊权限 SUID 定义 案例 原因 查找真个系统的SUID/SGID文件 SGID 定义&#xff1a; Sticky Bit 案例 设置文件和目录的特殊权限 方法一 使用 chmod命令 方法二 使用数字形式的权限模式 设置新建文件或目录的默认权限 设置修改文件的扩展性 设置文件…

MySQL连接查询——外连接

内连接查询顺序 首先看student和exam表的内容&#xff1a; 然后执行如下内连接查询&#xff1a; explain select a.*,b.* from student a inner join exam b on a.uidb.uid;查询计划如下 由于a表记录数量少为小表做全表扫描&#xff08;rows为6&#xff09;&#xff0c;然后到…

微信小程序标签知识点总结

View 标签 <scroll-view class"scroll_list" scroll-x"true"> 标签 设置 scroll-x/y是可以设置 滚动模式到底是x方向还是Y方向 &#xff08; 需要调整样式&#xff0c;请参考如下 .scroll_list{ border: 1px solid red; width: 240px; white-sp…

算法学习day21

文章目录 530.二叉搜索树的最小绝对差递归 501.二叉搜索树中的众数递归 236.二叉树的最近公共祖先递归 总结 530.二叉搜索树的最小绝对差 给你一个二叉搜索树的根节点 root &#xff0c;返回 树中任意两不同节点值之间的最小差值 。 差值是一个正数&#xff0c;其数值等于两值…

管理类联考——逻辑——知识篇——题型说明

管理类联考基础逻辑—逻辑规划 一、联考中逻辑部分的重要性 管理类综合能力测试的数学、逻辑、写作三个部分中&#xff0c;逻辑是毫无疑问最重要的一部分&#xff0c;体现在以下三个方面&#xff1a; 1、时间分配&#xff1a;逻辑部分的阅读量相当大&#xff0c;30道题的阅读…

2023史上最全java面试题题库大全800题含答案

如果你不停地加班。却很少冒险&#xff0c;也很少学习&#xff0c;那你极大可能会陷入到内卷中。 为什么这么说呢&#xff1f;我们先来捋清楚「内卷」的概念&#xff1a; 「内卷化」简而言之就是&#xff1a;日复一日&#xff0c;越混越掉坑里。 所谓内卷化&#xff0c;指一种社…

HTTP 网络通讯过程

1.知识点&#xff1a; 在计算机网络中&#xff0c;通信协议用于规范数据传输的格式和传送方式。下面是常见的网络通信协议&#xff1a; HTTP协议&#xff1a;超文本传输协议&#xff0c;用于在Web浏览器和Web服务器之间传输HTML文件和其他资源。 HTTPS协议&#xff1a;HTTP安…

《水经注地图服务》如何快速发布经纬度DAT缓存

概述 《水经注地图服务》的快速发布功能是一个能够帮助用户实现快速发布地图服务的功能&#xff0c;并且提供常规情况下大多数用户所需的默认配置&#xff0c;让用户在发布地图时更加便捷。 这里为大家演示如何快速发布经纬度DAT缓存以及如何在水经微图中加载。 准备工作 离…

2023-6-14-第五式原型模式

&#x1f37f;*★,*:.☆(&#xffe3;▽&#xffe3;)/$:*.★* &#x1f37f; &#x1f4a5;&#x1f4a5;&#x1f4a5;欢迎来到&#x1f91e;汤姆&#x1f91e;的csdn博文&#x1f4a5;&#x1f4a5;&#x1f4a5; &#x1f49f;&#x1f49f;喜欢的朋友可以关注一下&#xf…

IDEA中类模板注释和方法注释模板

类注释 /* *ClassName ${NAME} *Author --你的别名 *Description //TODO *Date ${DATE} ${TIME} *Version 1.0 **/ 把上面的代码粘贴到settings-editor-file and code templates下的class的“public class”和#parese的中间 2.方法注释 /* *Author --你的别名 *Description …

ZK+麦克风:反AI音频认证

1. 引言 当前&#xff0c;已越来越难以区分AI生成的音频与人类的声音。可能带来欺诈、身份盗用以及其它滥用问题。 在AI生成的音频可以完美模仿人声的当前环境中&#xff0c;需要一个可靠的信任链——从最初的音频捕获到最终的播放。这种信任链可以使用加密技术建立&#xff…

Java实训日志04

文章目录 八、项目开发实现步骤&#xff08;六&#xff09;创建数据访问接口1、创建学校数据访问接口2、创建状态数据访问接口3、创建学生数据访问接口4、创建用户数据访问接口 八、项目开发实现步骤 &#xff08;六&#xff09;创建数据访问接口 DAO: Data Acess Object - 数…