当前位置: 首页 > news >正文

Cursor 教我学 Python

文章目录

    • 1. 写在最前面
    • 2. Python 语法
      • 2.1 yield
        • 2.1.1 yield 和 return 的区别
        • 2.1.2 golang 中实现 yield 语法
    • 3. aiohttp 库
      • 3.1 原始写法
      • 3.2 修改写法
      • 3.2 耗时对比分析
    • 4. 碎碎念
    • 5. 参考资料

1. 写在最前面

最近加了很多 Python Coding 的任务,虽然在 AI 加持下能够顺利完成,但是还是觉得心理不踏实,觉得很多代码 AI 写完自己不是很懂,不喜欢这种感觉。

刚好周日上午没事,抽空记录在 Python 开发中遇到的神奇语法和库。

2. Python 语法

2.1 yield

修改的代码中,函数的返回很多处用了 Yield 而不是 return ,这引起了我的好奇。

2.1.1 yield 和 return 的区别

在 Python 中,yieldreturn 都用于从函数中返回值,但它们之间有一些重要的区别:

  • 返回类型

    • return:

      • return 语句用于结束函数的执行,并将一个值返回给调用者。函数在执行到 return 时会立即退出。

      • 每次调用函数时,都是从头开始执行,直到遇到 return

    • yield:

      • yield 语句用于定义生成器函数。生成器函数在执行时不会立即返回值,而是返回一个生成器对象。

      • 当生成器函数被调用时,它不会立即执行,而是返回一个生成器对象。可以通过迭代这个生成器对象来逐步执行函数的代码,每次遇到 yield 时返回一个值,并在下一次迭代时从上次停止的地方继续执行。

  • 内存使用

    • return:

      • 返回一个完整的结果(例如一个列表),可能会占用较多内存,特别是当结果很大时。
    • yield:

      • 生成器按需生成值,通常会更节省内存,特别是在处理大型数据集时,因为它不会一次性生成所有结果。
  • yield 的使用场景:

    • 内存效率:适合处理大数据集,避免一次性加载。

    • 无限序列:可生成无限序列,按需计算。

    • 状态保持:在函数中保持状态,适合需要维护状态的场景。

    • 协程:在异步编程中用于协作式多任务。

    • 管道处理:构建数据处理管道,方便数据流动。

  • 示例

    • 使用 return 的函数:

      def get_squares(n):return [x*x for x in range(n)]squares = get_squares(5)
      print(squares)  # 输出: [0, 1, 4, 9, 16]
      
    • 使用 yield 的生成器:

      def get_squares(n):for x in range(n):yield x*xsquares_gen = get_squares(5)
      for square in squares_gen:print(square)  # 输出: 0, 1, 4, 9, 16
      
2.1.2 golang 中实现 yield 语法

之前写的是 golang ,为了用类比法更好的理解 yield ,可以在 golang 中实现一个类似能力的示例。

package mainimport ("fmt"
)// 生成器函数,返回一个通道
func getSquares(n int) <-chan int {ch := make(chan int) // 创建一个通道go func() {for x := 0; x < n; x++ {ch <- x * x // 将计算结果发送到通道}close(ch) // 关闭通道,表示没有更多值}()return ch // 返回通道
}func main() {squares := getSquares(5) // 获取生成器通道for square := range squares { // 迭代通道中的值fmt.Println(square) // 输出: 0, 1, 4, 9, 16}
}

函数说明:

  • 通道:在 getSquares 函数中,我们创建了一个通道 ch,用于发送计算结果。

  • goroutine:我们使用 go 关键字启动了一个 goroutine,在这个 goroutine 中计算平方并将结果发送到通道。

  • 关闭通道:当所有值都发送完后,我们关闭通道,以便接收方知道没有更多值可供接收。

  • 迭代通道:在 main 函数中,我们使用 range 迭代通道,从中接收值。

3. aiohttp 库

需求是需要在客户请求大模型前,提前发送一次请求大模型,确保在客户请求的时候,就可以节省掉 tls 握手和 tcp 建立连接的时间,简称之为预热。

3.1 原始写法

async def analyze_backend_consistency(num_requests: int = 5, delay: float = 0.5, concurrent: bool = False):# 顺序发送请求results = []for i in range(num_requests):try:connector = aiohttp.TCPConnector(ssl=True)async with aiohttp.ClientSession(connector=connector) as session:result = await make_request(session, i + 1)results.append(result)if i < num_requests - 1:await asyncio.sleep(delay)except Exception as e:print(f"请求 {i + 1} 失败: {str(e)}")# 打印每个请求的结果for result in results:print(f"\n请求 {result['request_id']} 结果:")print(f"远程IP:端口 = {result['remote_ip']}:{result['remote_port']}")print(f"请求ID = {result['x_request_id']}")print(f"处理时间 = {result['upstream_time']}ms")print(f"总响应时间 = {result['response_time']}ms")print("-" * 50)# 分析结果print("\n分析结果:")unique_ips = set(r['remote_ip'] for r in results)print(f"使用的不同IP数量: {len(unique_ips)}")print(f"IP列表: {', '.join(str(ip) for ip in unique_ips)}")# 计算平均响应时间avg_response_time = sum(float(r['response_time']) for r in results) / len(results)print(f"平均响应时间: {avg_response_time:.2f}ms")# 检查是否所有请求都使用了同一个连接print(f"所有请求是否使用同一个连接: {len(unique_ips) == 1}")# 分析处理时间upstream_times = [float(r['upstream_time']) for r in results]print(f"后端处理时间范围: {min(upstream_times):.2f}ms - {max(upstream_times):.2f}ms")print(f"后端处理时间平均值: {sum(upstream_times)/len(upstream_times):.2f}ms")

测试结果:

在这里插入图片描述

3.2 修改写法

async def analyze_backend_consistency(num_requests: int = 5, delay: float = 0.5, concurrent: bool = False):connector = aiohttp.TCPConnector(ssl=True)async with aiohttp.ClientSession(connector=connector) as session:results = []if concurrent:# 并发发送所有请求tasks = [make_request(session, i + 1) for i in range(num_requests)]results = await asyncio.gather(*tasks)else:# 顺序发送请求for i in range(num_requests):try:result = await make_request(session, i + 1)results.append(result)if i < num_requests - 1:await asyncio.sleep(delay)except Exception as e:print(f"请求 {i + 1} 失败: {str(e)}")# 打印每个请求的结果for result in results:print(f"\n请求 {result['request_id']} 结果:")print(f"远程IP:端口 = {result['remote_ip']}:{result['remote_port']}")print(f"请求ID = {result['x_request_id']}")print(f"处理时间 = {result['upstream_time']}ms")print(f"总响应时间 = {result['response_time']}ms")print("-" * 50)# 分析结果print("\n分析结果:")unique_ips = set(r['remote_ip'] for r in results)print(f"使用的不同IP数量: {len(unique_ips)}")print(f"IP列表: {', '.join(str(ip) for ip in unique_ips)}")# 计算平均响应时间avg_response_time = sum(float(r['response_time']) for r in results) / len(results)print(f"平均响应时间: {avg_response_time:.2f}ms")# 检查是否所有请求都使用了同一个连接print(f"所有请求是否使用同一个连接: {len(unique_ips) == 1}")# 分析处理时间upstream_times = [float(r['upstream_time']) for r in results]print(f"后端处理时间范围: {min(upstream_times):.2f}ms - {max(upstream_times):.2f}ms")print(f"后端处理时间平均值: {sum(upstream_times)/len(upstream_times):.2f}ms")

测试结果:
在这里插入图片描述

3.2 耗时对比分析

原始写法修改写法
特点每个请求都创建新的 TCPConnector 和 ClientSession
每次请求都要重新建立 TCP 连接和 TLS 握手
不复用 HTTP/2 连接
每个请求的耗时 = TCP建立(~40ms) + TLS握手(~200ms) + 请求处理时间
只创建一次 TCPConnector 和 ClientSession
TCP 连接和 TLS 握手只进行一次
复用 HTTP/2 连接
第一个请求耗时 = TCP建立 + TLS握手 + 请求处理时间
后续请求耗时 = 请求处理时间

4. 碎碎念

周日的时候写了 80%,今晚刚好手里的活搞的差不多了,给总结收个尾。上海最近的暴雨和雷声有点子吓人:

  • 世间最重要的事莫过于懂得让自己属于自己。

  • 偶尔觉得妈妈很丢人,妈妈为什么连起码的脸面的自尊都没有呢?我都觉得上火。比起她自己,她有更想守护的,那就是我。人真正变强大,不是因为守护着自尊心,而是抛开自尊心的时候。所以妈妈很强大。

这周就要回去看妈妈啦,开心,就写到这里吧。

5. 参考资料

  • 如何理解Python中的yield用法?
  • https://docs.aiohttp.org/en/stable/tracing_reference.html#aiohttp-client-tracing-reference

文章转载自:

http://YYuR6Vp7.rkwLg.cn
http://jvDMKKXD.rkwLg.cn
http://MIXs0fYT.rkwLg.cn
http://lItitehO.rkwLg.cn
http://d2PUSj6E.rkwLg.cn
http://fqYXtS7r.rkwLg.cn
http://Fch3zNyB.rkwLg.cn
http://ZNY1REEK.rkwLg.cn
http://7VgbzXoS.rkwLg.cn
http://yDukG4TA.rkwLg.cn
http://YTCMZ3yB.rkwLg.cn
http://XEUyCpvD.rkwLg.cn
http://Mwpx56P5.rkwLg.cn
http://SC4YTVWt.rkwLg.cn
http://RvsGVQBa.rkwLg.cn
http://XnKWba31.rkwLg.cn
http://F0sKpBDC.rkwLg.cn
http://1hgNMRt1.rkwLg.cn
http://UsOwD77W.rkwLg.cn
http://zdFOz1px.rkwLg.cn
http://zFkByUs4.rkwLg.cn
http://tTkg9aoc.rkwLg.cn
http://GYIvYFie.rkwLg.cn
http://0aFADe7Z.rkwLg.cn
http://Hq7gmOdo.rkwLg.cn
http://iTVODB2m.rkwLg.cn
http://5OiinVsl.rkwLg.cn
http://2hzWKBWF.rkwLg.cn
http://Rh3gZqxM.rkwLg.cn
http://F1YiVcD3.rkwLg.cn
http://www.dtcms.com/a/363273.html

相关文章:

  • 基于 HTML、CSS 和 JavaScript 的智能图像锐化系统
  • JSON Schema 格式详解、版本介绍和示例教程
  • 简单爬一个小说页面 HTML 的title和内容
  • Python生成Excel
  • 点燃汽车电子与高端制造的“合规·高效·智能”引擎—— 全星研发项目管理软件系统APQP软件系统
  • CH01-1.2 Variable separable equation-Ordinary Differential Equation-by LiuChao
  • [架构之美]pdf压缩实战笔记(十五)
  • 【Unity Shader学习笔记】(一)计算机图形学概述
  • vue2 vue-property-decorator 库就类似于Java的注解库 vue class类编程
  • 阿里云和华为云Rocky LINUX 9.X镜像就绪及低端可用英伟达GPU
  • 力扣hot100:除自身以外数组的乘积(除法思路和左右前缀乘积)(238)
  • 静态ip软件哪个好用?资深用户的选择指南
  • Vite 插件 @vitejs/plugin-legacy 深度解析:旧浏览器兼容指南
  • 快速实现PLC之间的通信-基恩士
  • Spring Boot 全局字段处理最佳实践
  • 【程序员必备的Linux信号处理知识】
  • 【通用视觉框架】基于Python+OpenCV+PyQt5开发的视觉框架软件,全套源码,开箱即用
  • 变频器实习DAY41 单元测试介绍
  • % g++ *.cpp ...: fatal error: ‘opencv2/opencv.hpp‘ file not found 1
  • 趣味学RUST基础篇(错误处理)
  • Delphi 5 操作Word表格选区问题解析
  • 大数据毕业设计选题推荐-基于大数据的电脑硬件数据分析系统-Hadoop-Spark-数据可视化-BigData
  • 水电站电动机绝缘安全 “不掉线”!在线监测方案筑牢发电保障
  • ReactAgent接入MCP服务工具
  • 拷打字节面试官之-吃透c语言-哈希算法 如何在3面拷打字节cto 3万行算法源码带你吃透算法面试所有考题
  • C/C++条件编译:深入理解#ifndef/#endif守卫
  • 20.Linux进程信号(一)
  • C++拷贝语义和移动语义,左值引用与右值引用
  • 汉得H-AI飞码智能编码助手V1.2.4正式发布!
  • Turso数据库:用Rust重构的下一代SQLite——轻量级嵌入式数据库的未来选择