Python之Class按照某个元素排序
下边是一个例子,对Departs列表中的元素(均为Department类型)按照’id’,'name’两个属性排序(优先级依次减弱)
import operator # 导入operator 包,pip install operator
Departs = [] # 待排序列表
class Department: # 自定义的元素
def __init__(self, id, name, id2):
self.id = id
self.name = name
self.id2 = id2
# 创建元素和加入列表
Departs.append(Department(1, 'cbc', '1'))
Departs.append(Department(2, 'acd', '4'))
Departs.append(Department(3, 'bcd', '1'))
Departs.append(Department(1, 'bcd', '1'))
Departs.append(Department(2, 'acd', '3'))
# 划重点#划重点#划重点----排序操作
cmpfun = operator.attrgetter('id2') # 参数为排序依据的属性,可以有多个,这里优先id,使用时按需求改换参数即可
Departs.sort(key=cmpfun) # 使用时改变列表名即可
# 划重点#划重点#划重点----排序操作
# 此时Departs已经变成排好序的状态了,排序按照id优先,其次是name,遍历输出查看结果
for depart in Departs:
print(str(depart.id) + depart.name + depart.id2)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
解释都在注释中,输出结果为:
可以看到
1.列表已经改变;
2.id和name都相同的两个部门的先后顺序未改变,说明该排序算法具有稳定性
一般性方法:
1.首先导入operator包,pip install operator
2.关键操作为定义cmpfun 和使用.sort,即:
cmpfun = operator.attrgetter(‘a’,‘b’) #这里是希望按照a,b两个属性排序,且优先按照a属性,使用时更换参数即可。
list.sort(key=cmpfun)#list为待排序列表
优先按照a属性,使用时更换参数即可。
list.sort(key=cmpfun)#list为待排序列表
在SpringBoot中实现一个拦截器(HandlerInterceptor),用于获取请求的入参并将其转化为 Java 对象。
方式一:拦截器配合过滤器
1. 设计思路
在 Web 开发中,当 HTTP 请求发送到服务器时,Spring 会通过一个链条处理这个请求,这个链条包括很多组件,比如:拦截器(HandlerInterceptor
)、过滤器(Filter
)、控制器(Controller)、参数解析器(比如 Spring MVC 的 @RequestParam
或 @RequestBody
等注解)等。
输入流的问题
当客户端通过 POST
请求发送数据时,数据通常是包含在请求体中的(比如表单数据或者 JSON 数据)。Spring 的 HttpServletRequest
提供了 getInputStream()
方法来读取请求体中的数据。
问题: HttpServletRequest.getInputStream()
只能读取一次。也就是说,当你在拦截器中调用了 getInputStream()
读取数据时,流就被消费掉了,后续的组件(例如,Spring 的参数解析器)再调用 getInputStream()
就无法读取到数据了,因为流已经被关闭了。
解决方案
解决这个问题的思路是:在拦截器中读取请求体的数据时,不直接从 HttpServletRequest
中读取,而是通过包装(HttpServletRequestWrapper
)的方式,重新实现 getInputStream()
,将读取的数据缓存下来,确保后续的处理链依然能够访问到请求体的内容。
2. 如何实现
- 创建一个
HttpServletRequestWrapper
类:它将重写getInputStream()
方法,让流的数据可以多次读取。通过这个类缓存请求体的内容。 - 创建一个
Filter
:用于包装请求,将HttpServletRequest
包装成我们自己的HttpServletRequestWrapper
。 - 在拦截器中获取请求体:在
HandlerInterceptor
中获取请求体并进行解析。
3. 实现步骤
3.1 创建 HttpServletRequestWrapper
这个类主要作用是缓存请求体内容,并且重写 getInputStream()
,让它能够多次读取。
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
public class CachedBodyHttpServletRequestWrapper extends HttpServletRequestWrapper {
private byte[] requestBody;
public CachedBodyHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
// 从 InputStream 读取数据,缓存请求体内容
InputStream inputStream = request.getInputStream();
this.requestBody = inputStream.readAllBytes(); // 将流中的数据读取到字节数组中
}
@Override
public InputStream getInputStream() throws IOException {
// 返回缓存的数据
return new ByteArrayInputStream(requestBody);
}
public byte[] getRequestBody() {
return requestBody;
}
}
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
评论记录:
回复评论: