学python的第十九天

网络通信和访问数据库

1.1 基本的网络知识

@TCP/IP

       IP是低级的路由协议,它将数据拆分在许多小的数据包中,并通过网络将他们发送到某一特定地址,但无法保证所有包都抵达目的地,也不能保证包按顺序抵达

       TCP(传输控制协议),是一种高层协议,是面向连接的可靠数据传输协议,数据包未收到,会重发,并对数据包进行准确性检查,保证数据包按顺序抵达。

@IP地址,IPv4和IPv6

       特殊IP地址,127.0.0.1回送地址,只进行本机进程间通信,不进行任何网络传输

@端口(范围:0~65535,小于1024的保留给预定义的服务,如HTTP,80    FTP,20/21   Telnet,23   Email,25等等)

       网络通信程序运行提供网络服务或进行通信,需要不同的端口号进行通信,不仅要指定IP地址,还要指定端口号

@HTTP(端口80)/HTTPS(端口443)

HTTP(超文本传输协议)

HTTP/1.1共定义了8种请求方法,GET和POST方法最常用

HTTPS(超文本传输安全协议):HTTP+SSL,用于提供加密通信及对网络服务器身份的鉴定

1.2 搭建自己的Web服务器

1,安装JDK(java开发工具包)

2,配置java运行环境

3,安装Apache Tomcat服务器

4,启动Apache Tomcat服务器

1.3 urllib.request模块

1,发送GET请求

# 发送GET请求,获取响应
import urllib.request  # 导入urllib.request模块url = 'http://www.baidu.com/?action=query&ID=10'   # 请求URL网址,?后的内容是请求参数,多个参数用&分隔,例如action是参数名,query是参数值req = urllib.request.Request(url)  # 创建一个请求对象,默认是GET请求with urllib.request.urlopen(req) as response:  # 发送请求,并获取响应对象,可是使用with as代码块管理和释放data = response.read()      # 读取数据,为字节序列数据json_data = data.decode()   # 将字节序列数据转换为字符串print(json_data)   # 输出字符串数据
2,发送POST请求,提交数据
# 发送POST请求,提交数据import urllib.request  # 导入urllib.request模块url = 'http://www.baidu.com/'# 准备HTTP参数
params_dict = {'action': 'query', 'ID': '10'}
params_str = urllib.parse.urlencode(params_dict)  # 将字典转换为URL参数字符串
print(params_str)# 字符串转换为字节序列数据
params_bytes = params_str.encode()# 创建一个请求对象,设置请求方法为POST
req = urllib.request.Request(url, data=params_bytes)  # 发送POST请求,并设置请求方法为POSTwith urllib.request.urlopen(req) as response:  # 发送请求,并获取响应对象,可使用with as代码块管理和释放data = response.read()      # 读取数据,为字节序列数据json_data = data.decode()   # 将字节序列数据转换为字符串print(json_data)   # 输出字符串数据

1.4 JSON数据 

JSON(JavaScript Object Notation)

构成JSON文档的两种结构为:JSON对象(object)和JSON数组(array)

@1.4.1 JSON对象类似于python中的字典类型

JSON数据中的解码(decode)指将JSON数据转换为python数据,当从网络中接收或从磁盘中读取JSON数据时,需要将其解码为Python数据

{

"name": "a.htm",

"size": "345",

"saved": "true"

}

@1.4.2 JSON数组类似于python中的列表类型,示例如下:

    "text","html","css"

]

@1.4.3 JSON的数值有字符串,数字,true,false,null,对象或数组。null表示空的对象,而且对象和数组可以嵌套

@1.4.4 使用json模块提供的loads(str)函数进行JSON数据的解码,参数str是JSON字符串,返回python数据。

代码示例:

import urllib.request  # 导入urllib.request模块
import json    # 导入json模块url = 'http://www.baidu.com/?action=query&ID=10'   # 请求URL网址,?后的内容是请求参数,多个参数用&分隔,例如action是参数名,query是参数值req = urllib.request.Request(url)  # 创建一个请求对象,默认是GET请求with urllib.request.urlopen(req) as response:  # 发送请求,并获取响应对象,可是使用with as代码块管理和释放data = response.read()      # 读取数据,为字节序列数据json_data = data.decode()   # 将字节序列数据转换为字符串print('JSON字符串:', json_data)   # 输出字符串数据py_dict = json.load(json_data)   # 解码json字符串,返回字典print('备忘录ID:', py_dict['ID'])print('备忘录日期:', py_dict['CDate'])print('备忘录内容:', py_dict['Content'])print('用户ID:', py_dict['UserID'])

@1.4.5 下载图片示例

# 1.4 下载图片示例
import urllib.request  # 导入urllib.request模块url = 'http://www.baidu.com/img/logo.png'req = urllib.request.Request(url)  # 创建一个请求对象,默认是GET请求with urllib.request.urlopen(req) as response:  # 发送请求,并获取响应对象,可使用with as代码块管理和释放data = response.read()  # 读取数据,为字节序列数据f_name = 'logo.png'  # 文件名with open(f_name, 'wb') as f:  # 创建文件对象,并设置写入模式,wb表示写入二进制数据f.write(data)  # 将字节序列数据写入文件print('图片下载完成')

@1.4.6 返回所有备忘录信息示例

# 1.5 返回所有备忘录信息
import urllib.request  # 导入urllib.request模块
import jsonurl = 'http://www.baidu.com/'  # 请求URL网址req = urllib.request.Request(url)  # 创建一个请求对象,默认是GET请求with urllib.request.urlopen(req) as response:  # 发送请求,并获取响应对象,可是使用with as代码块管理和释放data = response.read()  # 读取数据,为字节序列数据json_data = data.decode()  # 将字节序列数据转换为字符串py_dict = json.load(json_data)  # 解码json字符串,返回字典record_array = py_dict['Record']  # 获取备忘录数组for record_obj in record_array:print('--------备忘录信息--------')print('备忘录ID:', record_obj['ID'])print('备忘录日期:', record_obj['CDate'])print('备忘录内容:', record_obj['Content'])print('用户ID:', record_obj['UserID'])

2.1 SQLite数据库 

SQLite是嵌入式系统使用的关系数据库,目前的主流版本是SQLite 3。SQLite是开源的,采用C语言编写而成,具有可移植性强、可靠性高 、小而易用等特点。SQLite提供了对SQL-92标准的支持,支持多表、索引、事务、视图和触发。

@2.1.1 SQLite的数据类型,是无数据类型的数据库

支持的数据类型:

INTEGER(有符号的整数类型)

REAL(浮点类型)

TEXT(字符串类型,采用UTF-8,UTF-16)

BLOB(二进制大对象类型,能够存放任意二进制数据)

@2.1.2  Python数据类型与SQLite数据类型的映射

Python数据类型SQLite数据类型
NoneNULL
intINTEGRE
floatREAL
strTEXT
bytesBLOB

 @2.1.3 使用GUI管理工具管理SQLite数据库

如DB Browser for SQLite。

自行下载安装,打开后如下图

1. 创建数据库

2.创建数据表

3.执行SQL语句

4.浏览数据 

 2.2 数据库编程的基本操作

数据库编程主要分为两类:查询(Read)和修改(C插入,U更新,D删除)

查询数据和修改数据

2.3 sqlite3模块API(使用此模块访问数据库)

@ 2.3.1 数据库连接对象Connection

访问第一步是数据库连接

通过connect(database)函数建立数据库连接,参数database是SQLite数据库的文件路径,连接成功,返回数据库连接对象Connection。

Connection有如下重要方法:

close()关闭数据库连接,关闭之后再使用数据库连接将引发异常

commit()提交数据库事务

rollback()回滚数据库事务

cursor()获得Cursor游标对象

@ 2.3.2 游标对象Cursor

一个Cursor游标对象表示一个数据库游标,游标暂时保存了SQL操作所影响到的数据。游标是通过数据库连接创建的。

游标Cursor对象有很多方法和属性,其中的基本SQL操作方法如下:

execute(sql[,parameters]):执行一条SQL语句,sql是SQL语句 ,parameters是为SQL提供的参数,可以是序列或字典类型。返回值是 整数,表示执行SQL语句影响的行数。

executemany(sql[,seq_of_params]):执行批量SQL语句,sql是S QL语句,seq_of_params是为SQL提供的参数,seq_of_params是序列。 返回值是整数,表示执行SQL语句影响的行数。

在通过execute()和executemany()方法执行SQL查询语句后, 还要通过提取方法从查询结果集中返回数据,相关提取方法如下:

fetchone():从结果集中返回只有一条记录的序列,如果没有数 据,则返回None。

fetchmany(size=cursor.arraysize):从结果集中返回小于等于size 记录数的序列,如果没有数据,则返回空序列,size在默认情况下是整 个游标的行数。

fetchall():从结果集中返回所有数据。

2.4 数据库的CRUD操作示例

@2.4.1 数据插入(Creat)

 数据插入操作的SQL语句INSERT,代码如下:

import sqlite3  # 导入sqlite3模块
import os# 数据库文件路径
db_path = r'D:\桌面文件\DB\新建数据库的相关文件\school_db.db'# 检查文件是否存在
if not os.path.exists(db_path):print(f"数据库文件 {db_path} 不存在!")
i_name = input('请输入姓名:')  # 获取用户输入的姓名
i_sex = input('请输入性别(1表示男,0表示女):')  # 获取用户输入的性别
i_birthday = input('请输入生日(YYYYMMDD):')  # 获取用户输入的生日try:# 连接到SQLite数据库con = sqlite3.connect(r'D:\桌面文件\DB\新建数据库的相关文件\school_db.db')# 创建一个Cursor对象,用于执行SQL命令cursor = con.cursor()# 执行SQL查询操作sql = 'INSERT INTO  student(s_name, s_sex, s_birthday) VALUES (?, ?, ?)'cursor.execute(sql, [i_name, i_sex, i_birthday])  # 执行SQL命令,参数放到序列或元组中# 提取数据库事务con.commit()print('插入成功!')except sqlite3.Error as e:print('插入数据失败:{}'.format(e))# 回滚数据库事务con.rollback()finally:# 关闭游标if cursor:cursor.close()# 关闭数据库连接if con:con.close()

@2.4.2 数据查询(Read)

SQL查询语句是SELECT,根据是否带有WHERE子句,分为:无条件查询和有条件查询

***********无条件查询,没有WHERE子句**********,代码如下:

import sqlite3  # 导入sqlite3模块
import os# 数据库文件路径
db_path = r'D:\桌面文件\DB\新建数据库的相关文件\school_db.db'# 检查文件是否存在
if not os.path.exists(db_path):print(f"数据库文件 {db_path} 不存在!")try:# 连接到SQLite数据库con = sqlite3.connect(r'D:\桌面文件\DB\新建数据库的相关文件\school_db.db')# 创建一个Cursor对象,用于执行SQL命令cursor = con.cursor()# 执行SQL查询操作sql = 'SELECT s_id, s_name, s_sex, s_birthday FROM student'cursor.execute(sql)  # 执行SQL命令# 提取结果集result_set = cursor.fetchall()for row in result_set:print('学号:{0} - 姓名:{1} - 性别:{2} - 生日:{3}'.format(row[0], row[1], row[2], row[3]))except sqlite3.Error as e:print('数据库查询发生错误:{}'.format(e))finally:# 关闭游标if cursor:cursor.close()# 关闭数据库连接if con:con.close()

 *************有条件查询**************有WHERE子句,WHERE子句是查询条件,

代码如下:

# 有条件查询,有WHERE子句,WHERE自己是查询条件
import sqlite3  # 导入sqlite3模块
import os# 数据库文件路径
db_path = r'D:\桌面文件\DB\新建数据库的相关文件\school_db.db'# 检查文件是否存在
if not os.path.exists(db_path):print(f"数据库文件 {db_path} 不存在!")istr = input('请输入生日(YYYYMMDD):')  # 获取用户输入的生日try:# 连接到SQLite数据库con = sqlite3.connect(r'D:\桌面文件\DB\新建数据库的相关文件\school_db.db')# 创建一个Cursor对象,用于执行SQL命令cursor = con.cursor()# 执行SQL查询操作sql = 'SELECT s_id, s_name, s_sex, s_birthday FROM student WHERE s_birthday < ?'  # 查询学生信息cursor.execute(sql, [istr])  # 执行SQL命令,参数放到序列或元组中# 提取结果集result_set = cursor.fetchall()for row in result_set:print('学号:{0} - 姓名:{1} - 性别:{2} - 生日:{3}'.format(row[0], row[1], row[2], row[3]))except sqlite3.Error as e:print('数据库查询发生错误:{}'.format(e))finally:# 关闭游标if cursor:cursor.close()# 关闭数据库连接if con:con.close()

@2.4.3 数据更新(Update)

数据更新操作的SQL语句是UPDATE。示例如下:

import sqlite3  # 导入sqlite3模块
import os# 数据库文件路径
db_path = r'D:\桌面文件\DB\新建数据库的相关文件\school_db.db'# 检查文件是否存在
if not os.path.exists(db_path):print(f"数据库文件 {db_path} 不存在!")
i_id = input('请输入学号:')  # 获取用户输入的学号
i_name = input('请输入姓名:')  # 获取用户输入的姓名
i_sex = input('请输入性别(1表示男,0表示女):')  # 获取用户输入的性别
i_birthday = input('请输入生日(YYYYMMDD):')  # 获取用户输入的生日try:# 连接到SQLite数据库con = sqlite3.connect(r'D:\桌面文件\DB\新建数据库的相关文件\school_db.db')# 创建一个Cursor对象,用于执行SQL命令cursor = con.cursor()# 执行SQL查询操作sql = 'UPDATE  student SET s_name=?, s_sex=?, s_birthday=? WHERE s_id=?'cursor.execute(sql, [i_name, i_sex, i_birthday, i_id])  # 执行SQL命令,参数放到序列或元组中# 提取数据库事务con.commit()print('更新数据库成功')except sqlite3.Error as e:print('更新数据库失败:{}'.format(e))# 回滚数据库事务con.rollback()finally:# 关闭游标if cursor:cursor.close()# 关闭数据库连接if con:con.close()

@2.4.4数据删除(Delete)

数据删除操作SQL语句是DELETE。示例如下:

import sqlite3  # 导入sqlite3模块
import os# 数据库文件路径
db_path = r'D:\桌面文件\DB\新建数据库的相关文件\school_db.db'# 检查文件是否存在
if not os.path.exists(db_path):print(f"数据库文件 {db_path} 不存在!")
i_id = input('请输入要删除学生的学号:')  # 获取学号try:# 连接到SQLite数据库con = sqlite3.connect(r'D:\桌面文件\DB\新建数据库的相关文件\school_db.db')# 创建一个Cursor对象,用于执行SQL命令cursor = con.cursor()# 执行SQL查询操作sql = 'DELETE  FROM student  WHERE s_id=?'cursor.execute(sql, [i_id])  # 执行SQL命令,参数放到序列或元组中# 提取数据库事务con.commit()print('删除数据成功')except sqlite3.Error as e:print('删除数据失败:{}'.format(e))# 回滚数据库事务con.rollback()finally:# 关闭游标if cursor:cursor.close()# 关闭数据库连接if con:con.close()

可以看到下图s_id=5的学生张三被删除 

2.5 防止 SQL注入攻击

示例如下:

import sqlite3  # 导入sqlite3模块
import os# 数据库文件路径
db_path = r'D:\桌面文件\DB\新建数据库的相关文件\school_db.db'# 检查文件是否存在
if not os.path.exists(db_path):print(f"数据库文件 {db_path} 不存在!")istr = input('请输入生日(YYYYMMDD):')  # 获取用户输入的生日try:# 连接到SQLite数据库con = sqlite3.connect(r'D:\桌面文件\DB\新建数据库的相关文件\school_db.db')# 创建一个Cursor对象,用于执行SQL命令cursor = con.cursor()# 执行SQL查询操作
#    sql = 'SELECT s_id, s_name, s_sex, s_birthday FROM student WHERE s_birthday < ?'  # 查询学生信息
#    cursor.execute(sql, [istr])  # 执行SQL命令,参数放到序列或元组中sql = 'SELECT s_id, s_name, s_sex, s_birthday FROM student WHERE s_birthday < ' + istr  # 查询学生信息,这种方式容易造成,SQL注入攻击cursor.execute(sql)  # 执行SQL命令,参数放到序列或元组中# 提取结果集result_set = cursor.fetchall()for row in result_set:print('学号:{0} - 姓名:{1} - 性别:{2} - 生日:{3}'.format(row[0], row[1], row[2], row[3]))except sqlite3.Error as e:print('数据库查询发生错误:{}'.format(e))finally:# 关闭游标if cursor:cursor.close()# 关闭数据库连接if con:con.close()

图一是查询20050101之前的

图二SQL注入是查询所有数据,如果是删除,损失可想而知!!!! 

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

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

相关文章

深度学习系列65:数字人openHeygen详解

1. 主流程分析 从inference.py函数进入&#xff0c;主要流程包括&#xff1a; 1&#xff09; 使用cv2获取视频中所有帧的列表&#xff0c;如下&#xff1a; 2&#xff09;定义Croper。核心代码为69行&#xff1a;full_frames_RGB, crop, quad croper.crop(full_frames_RGB)。…

Android MVVM架构 + Retrofit完成网络请求

关于Retrofit&#xff0c;这个应该不是一个很新颖的东西了&#xff0c;简单过一下吧 1.由Square公司开发&#xff0c;基于Type-safe的REST客户端。 2.使用注解来定义API接口&#xff0c;使得HTTP请求变得简洁且易于维护。 3.支持同步和异步请求&#xff0c;可与RxJava、Corouti…

【安卓13】解决带GMS编译报super分区空间不足错误

1、错误信息 2、解决方案 不同供应商修改分区大小的文件路径不一样&#xff0c;但是万变不离其宗&#xff0c;根据报错信息全局搜索关键词BOARD_SUPER_PARTITION_SIZE 这里以RK供应商和AML供应商修改为例&#xff1a; &#xff08;1&#xff09;RK改法&#xff1a; 根目录下…

全光谱灯对人体的危害?谨记全光谱灯选购要避开的四大套路

全光谱灯对人体的危害有多大&#xff1f;近年来网上关于护眼台灯对视力有害的言论有很多&#xff0c;引发了很多人空前的关注&#xff0c;事实上这未必是一件坏事&#xff0c;因为随着护眼台灯的热度持续上涨&#xff0c;市面上浑水摸鱼的行为增多了不少&#xff0c;有着不少劣…

STM32H7使用FileX库BUG,SD卡挂载失败

问题描述&#xff1a; 使用STM32H7ThreadXFileX&#xff0c;之前使用swissbit牌的存储卡可正常使用&#xff0c;最近项目用了金士顿的存储卡&#xff0c;发现无法挂载文件系统。 原因分析&#xff1a; 调试过程发现&#xff0c;关闭D-Cache可以挂载使用exfat文件系统。 File…

一文看够,植物线粒体基因组分析套路

线粒体堪称生命活动的“能量供给站”&#xff0c;植物线粒体是线粒体基因组研究中难度最高的&#xff0c;其基因组大小差异较大&#xff0c;100kb-10Mb&#xff0c;大部分由非编码DNA序列组成&#xff0c;且有许多同源序列&#xff0c;占基因组总长的2%-60%&#xff0c;基因间区…

制作github.io学术个人主页

制作如图的学术个人主页。About me - Xianwen Ling’s Blog 学术个人主页是一个学者展示个人学术成果和研究方向的重要工具。个人主页可以集中展示学者的研究论文、出版物、演讲和发布的项目等学术成果&#xff0c;这样其他人可以更方便地了解和评估学者的研究贡献。个人主页可…

Maven 安装及配置教程(Windows)【安装】

文章目录 一、 下载1. 官网下载2. 其它渠道 二、 安装三、 配置四、 验证五、 本地仓储配置六、 配置镜像七、 配置JDK八、完整配置九、常用命令十、IDEA 中配置 Maven1. 配置当前项目2. 配置新建 / 新打开 项目 软件 / 环境安装及配置目录 一、 下载 1. 官网下载 安装地址&a…

书生·浦语大模型第二期实战营第七节-OpenCompass 大模型评测实战 笔记和作业

来源&#xff1a; 视频教程&#xff1a;https://www.bilibili.com/video/BV1Pm41127jU/?spm_id_from333.788&vd_sourcef4a51f7f5a63e756f73ad0dff318c1a3 文字教程&#xff1a;https://github.com/InternLM/Tutorial/blob/camp2/opencompass/readme.md 作业来源&#x…

【Hadoop】- MapReduce YARN 初体验[9]

目录 提交MapReduce程序至YARN运行 1、提交wordcount示例程序 1.1、先准备words.txt文件上传到hdfs&#xff0c;文件内容如下&#xff1a; 1.2、在hdfs中创建两个文件夹&#xff0c;分别为/input、/output 1.3、将创建好的words.txt文件上传到hdfs中/input 1.4、提交MapR…

HotSpot JVM 中的应用程序/动态类数据共享

0.前言 本文的目的是详细讨论 HotSpot JVM 自 JDK 1.5 以来提供的一项功能&#xff0c;该功能可以减少启动时间&#xff0c;但如果在多个 JVM 之间共享相同的类数据共享 (CDS) 存档&#xff0c;则还可以减少内存占用。 1.类数据共享 (CDS) CDS 的想法是使用特定格式将预处理…

状态模式和策略模式对比

状态模式和策略模式都是行为型设计模式&#xff0c;它们的主要目标都是将变化的行为封装起来&#xff0c;使得程序更加灵活和可维护。之所以将状态模式和策略模式进行比较&#xff0c;主要是因为两个设计模式的类图相似度较高。但是&#xff0c;从状态模式和策略模式的应用场景…

Pulsar Meetup 深圳 2024 会务介绍

“ Hi&#xff0c;各位热爱 Pulsar 的小伙伴们&#xff0c;Pulsar Meetup 深圳 2024 报名倒计时啦&#xff0c;快来报名。这里汇集了腾讯、华为和谙流科技等大量 Pulsar 大咖&#xff0c;干货多多&#xff0c;礼品多多&#xff0c;不容错过啊。 ” 活动介绍 由 AscentStream 谙…

Python 0基础_变现_38岁_day 16(文件操作)

在python&#xff0c;使用内置函数open()进行文件的一些读写操作 文件操作格式&#xff1a;open(文件路径&#xff0c;访问模式&#xff0c;字符编码) 前面两个参数是必备参数&#xff0c;后面的字符编码为选填&#xff0c;但是大多数情况下都会协商字符编码 访问模式 r 只读 w…

数码摄影色彩构成,数码相机色彩管理

一、资料描述 本套摄影色彩资料&#xff0c;大小58.54M&#xff0c;共有6个文件。 二、资料目录 《抽象彩色摄影集》.阿瑟.pdf 《色彩构成》.pdf 《色彩学》.星云.扫描版.pdf 《摄影色彩构成》.pdf 《数码相机色彩管理》.pdf 数码摄影进阶之4《色彩篇》.pdf 三、资料下…

解决IDEA中Tomcat控制台乱码问题(包括sout输出乱码)

文章目录 前言一、控制台直接输出乱码二、sout输出内容在控制台显示乱码 前言 今天在使用Tomcat的时候发现控制台输入出现了乱码问题&#xff0c;其实之前就出现过一次&#xff0c;解决了&#xff0c;但是新创建一个项目后又会出现sout的内容在控制台输出的乱码问题&#xff0…

Windows下Git的使用

目录 一、克隆远程仓库到本地二、git的三板斧2.1 add-将代码添加到本地仓库2.2 commit-提交代码到本地仓库2.3 push-推送本次添加操作到远程仓库2.4 gitee只有三板斧吗&#xff1f; 三、推送后没有出现绿点四、push到远程时报错五、git图形化界面下载链接 一、克隆远程仓库到本…

sql题目练习

cookie注入 解题思路和之前的整数型注入一样&#xff0c;只是比整数型注入多了一步&#xff0c;题目没有给输入框&#xff0c;提示“尝试找找cookie吧”cookie的中文翻译是曲奇&#xff0c;小甜饼的意思。cookie其实就是一些数据信息&#xff0c;类型为“小型文本文件”&#…

【CSS】CSS实现元素逐渐消失(实现元素透明逐渐消失/模糊)

mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 1) 10%);mask-image 属性用于定义一个遮罩&#xff0c;它可以隐藏元素的一部分或全部内容。在这个示例中&#xff0c;我们使用 mask-image 属性来定义一个线性渐变的遮罩&#xff0c;使得列表项的内…

如何用微信发布考试成绩(如月考、期中、期末等)

自教育部《未成年人学校保护规定》颁布后,教育部明确表示:学校不得公开学生的考试成绩、排名等信息!同时学校应采取措施,便利家长知道学生的成绩等学业信息,对于教师来说,如何用微信发布考试成绩(如:月考、期中、期末等)就成了一道难题... 公开吧,会伤害到学生自尊心,甚至被投诉…