【Python】实现限时循环的学习笔记

1 问题描述

今天我们在实现Emutouch时,有这样一个需求:我们希望在指定的时间内启动一个程序,如果超时就报错,类似于一种 “限时循环”的效果,理想的示例代码如下,

while Limited_time(10): # if timeout,`Limited_time` would throw an timeout error from inside# Here is the logic of checking if the program has startedif start_success:break

2 学习咨询

2.1 GPT-4-32k

南溪:您好,我们今天在编程时遇到一个小问题,我们希望用循环来检查一个程序是否已经启动,并给定一定的时间限制,如果超时就报错,也就是说,是否可以使用python实现一种“限时循环”的效果,期望效果的示例代码如下,

while Limited_time(10): # if timeout,`Limited_time` would throw an timeout error from inside# Here is the logic of checking if the program has startedif start_success:break

GPT-4-32k:你可以通过自定义一个带有超时功能的上下文管理器或者使用 time 模块来实现限时循环的效果。下面是一个简单的实现示例:

import timeclass LimitedTime:def __init__(self, timeout):self.timeout = timeoutself.start_time = Nonedef __enter__(self):self.start_time = time.time()return selfdef __exit__(self, exc_type, exc_value, traceback):passdef is_timeout(self):return time.time() - self.start_time > self.timeout# 使用示例
try:with LimitedTime(10) as timer:while True:if timer.is_timeout():raise TimeoutError("Timeout waiting for the program to start.")# 这里是检查程序是否已经启动的逻辑start_success = False # 假设这里是检查程序是否启动的结果if start_success:print("Program started successfully.")breaktime.sleep(1)  # 避免CPU过度占用
except TimeoutError as e:print(e)

在上面的代码中,LimitedTime 类定义了一个上下文管理器,它记录了开始的时间,并在每次循环中检查是否超出了设定的时间限制。如果超时,它会抛出一个 TimeoutError
请注意,在实际的代码实现中,你需要替换 # 这里是检查程序是否已经启动的逻辑 部分为你具体的逻辑代码,并根据实际情况设置合理的检查间隔(这里使用了 time.sleep(1) 作为示例)。
另外,TimeoutError 是一个内置的异常类型,可用于这种情况。如果你的环境中没有 TimeoutError,可以使用 Exception 或者自定义一个异常类型。

南溪:我感觉你给出的代码还是有点复杂,因为try:with limited_time(10): 会增加两行的缩进,是否可以实现成

while Limited_time(10): # if timeout,`Limited_time` would throw an timeout error from inside# Here is the logic of checking if the program has startedif start_success:break

这种简单的形式呢?

GPT-4-32k:要实现类似于这样的简洁语法结构,可以定义一个生成器函数,它会在超时时抛出一个异常。请看下面的示例:

import timeclass TimeoutError(Exception):passdef limited_time(timeout):start_time = time.time()while True:if time.time() - start_time > timeout:raise TimeoutError("Operation timed out.")yield# 使用示例
try:for _ in limited_time(10):# 这里是检查程序是否已经启动的逻辑start_success = False  # 假设这里是检查程序是否启动的结果if start_success:print("Program started successfully.")breaktime.sleep(1)  # 避免CPU过度占用
except TimeoutError as e:print(e)

在这个例子中,limited_time 函数是一个生成器,它会一直运行,直到超出指定的超时时间。在每次迭代时,它会检查是否已超时,一旦超时,则抛出TimeoutError异常。使用这个生成器的for循环就能够实现类似于你想要的“限时循环”的效果。

这种方式减少了代码的缩进层级,使得结构更为简洁。此外,limited_time生成器函数的设计使得它在其他地方也能复用,增加了代码的可维护性。

南溪:可以看到这里的代码跟我们期望的还是不一样,这里是用for循环实现的。

南溪:我感觉你给出的代码还是有点复杂,我期望将这样的逻辑封装成一个Limited_time()的结构来直接调用,这里的“for _ in limited_time(10):”是否可以直接简化成“while Limited_time(10):”这样呢?

GPT-4-32k:为了实现 while Limited_time(10): 这样的简洁结构,我们可以定义一个函数,它返回一个可以在 while 循环中使用的对象。这个对象需要有一个方法来不断检查是否超时。这里,我们可以使用一个迭代器来实现这个效果。

以下是一个可能的实现:

import timeclass TimeoutError(Exception):passclass Limited_time:def __init__(self, timeout):self.timeout = timeoutself.start_time = time.time()def __iter__(self):return selfdef __next__(self):if time.time() - self.start_time > self.timeout:raise TimeoutError("Operation timed out.")else:return True# 使用示例
try:while next(Limited_time(10)):# 这里是检查程序是否已经启动的逻辑start_success = False  # 假设这里是检查程序是否启动的结果if start_success:print("Program started successfully.")breaktime.sleep(1)  # 避免CPU过度占用
except TimeoutError as e:print(e)

在这个实现当中,Limited_time 类实例化时传入超时时间,它实现了 __iter____next__ 方法,使得它可以在 while 循环中使用。每次循环时,__next__ 方法会被调用,如果超时则抛出 TimeoutError 异常,否则继续循环。

尽管这种方法实现了 while Limited_time(timeout): 这样的语法,它仍然需要使用 try/except 块来捕获异常,因为这是处理超时错误的推荐方式。如果你不想捕获异常,你可以修改 __next__ 方法来返回一个布尔值而不是抛出异常,但这将改变你最初的需求(即在超时时抛出一个错误)。

南溪:
这里的代码明显是错误的,循环体while next(Limited_time(10)):每次都会生成一个新的对象,导致程序陷入死循环。

接下来我们咨询一下Claude教授。

2.2 Claude

南溪:您好,我们今天在编程时遇到一个小问题,我们希望用循环来检查一个程序是否已经启动,并给定一定的时间限制,如果超时就报错,也就是说,是否可以使用python实现一种“限时循环”的效果,期望效果的示例代码如下,

while Limited_time(10): # if timeout,`Limited_time` would throw an timeout error from inside# Here is the logic of checking if the program has startedif start_success:break

Claude:您好,您提到的"限时循环"可以使用Python的time模块来实现。具体做法是:

import timetimeout = 10 # seconds
starttime = time.time()
while True:if time.time() - starttime > timeout:raise TimeoutError("Timeout!")# 检查程序是否启动的逻辑if start_success: breaktime.sleep(0.1)

主要思路是:

  1. 设置一个超时时间timeout
  2. 在循环开始时记录当前时间starttime
  3. 在循环内部判断当前时间与starttime的时间差是否大于超时时间
  4. 如果超时就抛出TimeoutError异常
  5. 否则就执行正常的检查逻辑,如果程序启动就break退出循环

这里time.sleep可以添加一点延时,避免循环太快消耗CPU。

这个基本思路可以实现Python中的限时循环效果,请您参考是否符合需求。如果还有其他问题,欢迎继续讨论。

南溪:你在代码中使用了“while True:”,我感觉这种写法不是很优雅,能不能写成

while Limited_time(10): # if timeout,`Limited_time` would throw an timeout error from inside# Here is the logic of checking if the program has startedif start_success:break

我们期望的这种形式呢

Claude:您的意思是希望实现一个Limited_time的函数,来封装这个超时逻辑对吧?可以这样实现:

import timedef Limited_time(timeout):starttime = time.time()  while True:if time.time() - starttime > timeout:raise TimeoutError("Timeout!")yield# 使用
try:while Limited_time(10):# 检查程序启动逻辑if start_success:break
except TimeoutError as e:print(e) # 打印超时错误信息

我们实现一个Limited_time生成器函数,内部实现和之前类似,增加超时判断逻辑。

在外部通过while循环调用它,这样可以通过except捕获超时错误。

yield语句让该函数成为一个生成器,遍历它时内部的while True逻辑会执行。

这样就实现了您期望的形式,封装了超时逻辑,外部用while循环更简洁。请您检查下是否符合要求,如果还有其他问题欢迎继续讨论。

南溪:我感觉Claude给出的代码似乎有问题,我再询问一下;

南溪:你给出的def Limited_time(timeout)是一个“迭代器函数”吗?

Claude:对,我实现的Limited_time是一个生成器函数,它是一个迭代器。

生成器函数有以下几个特点:

  1. 包含yield语句
  2. 当调用时不会执行函数体代码,而是返回一个生成器对象
  3. 在遍历生成器对象时才会执行函数体内的代码
  4. 每次执行到yield时会暂停,并将yield后的值作为本次迭代的值
  5. 可以通过for循环遍历,也可以通过next()函数获取下一个迭代值

所以在这个例子中,Limited_time是一个生成器函数,包含yield语句。

在外部调用它时,不会执行while True循环,而是返回一个生成器对象。

在for或while循环遍历这个生成器对象时,才会进入Limited_time函数体,并执行while True循环。

每次执行到yield语句就会暂停并返回,实现了迭代的效果。

这就是生成器函数的关键特点,它实现了延迟执行和迭代效果。

所以您认识正确,Limited_time是一个迭代器函数/生成器函数,利用其迭代效果来实现了限时循环逻辑。

南溪:你给出的代码可能是错误的,因为“while Limited_time(10):”在每次while的循环检查时,都会调用新的函数,并没有发挥“迭代器”的作用,于是会导致程序陷入死循环

Claude:您的观点非常正确,我给出的代码的确有问题,会导致重复调用Limited_time而不是利用其迭代器特性。

我重新考虑了一下,应该这样改进:

import timedef Limited_time(timeout):# 代码同上timer = Limited_time(10) # 提前创建迭代器try:while True: start_time = next(timer) # 触发迭代器进到函数内部执行# 检查程序启动逻辑if start_success:breakexcept StopIteration:print("Timeout!") # 迭代器完成时触发StopIteration异常

关键点是:

  1. 提前创建迭代器对象timer,而不是在while内调用
  2. 在while内使用next(timer)触发迭代器进入函数内部执行
  3. 最后用except StopIteration捕获迭代完成的异常

这样就可以正确利用Limited_time的迭代器特性,避免重复调用产生死循环。

非常感谢您指出我示例代码的错误,帮我改进了解决方案。这确实是一个迭代器应用需要注意的地方。如有其他问题,欢迎继续讨论!

南溪:
给出的代码还是使用的while True:,并没有很好地实现我们的要求。

接下来我们咨询一下讯飞星火教授。

2.3 讯飞星火

南溪:您好,我们今天在编程时遇到一个小问题,我们希望用循环来检查一个程序是否已经启动,并给定一定的时间限制,如果超时就报错,也就是说,是否可以使用python实现一种“限时循环”的效果,期望效果的示例代码如下,

while Limited_time(10): # if timeout,`Limited_time` would throw an timeout error from inside# Here is the logic of checking if the program has startedif start_success:break

讯飞星火:可以使用Python的time模块实现这个功能。首先,我们需要记录循环开始的时间,然后在循环中检查当前时间与开始时间的差值是否超过了给定的时间限制。如果超过了时间限制,就抛出一个异常。示例代码如下:

import timeclass TimeoutError(Exception):passdef Limited_time(timeout):start_time = time.time()while True:current_time = time.time()if current_time - start_time > timeout:raise TimeoutError("Timeout")# 这里是检查程序是否启动的逻辑if start_success():breaktry:Limited_time(10)
except TimeoutError as e:print(e)

南溪:我感觉你给出的代码似乎跟我们期望的示例不太一样,在你给出的代码,你将“检查程序是否启动的逻辑”放在了“Limited_time”里面,而我们期望的用法中,“检查程序启动的逻辑”应该是在同一个上下文中

讯飞星火:对不起,我理解错了你的需求。你可以将检查程序是否启动的逻辑放在循环外,然后在循环中只进行超时判断。示例代码如下:

import timeclass TimeoutError(Exception):passdef Limited_time(timeout):start_time = time.time()while True:current_time = time.time()if current_time - start_time > timeout:raise TimeoutError("Timeout")# 这里是检查程序是否启动的逻辑if not start_success():breaktry:Limited_time(10)
except TimeoutError as e:print(e)

南溪:
给出的代码没有实现我们的要求,星火将“检查程序启动的逻辑”放在了Limited_time内部。

南溪:你这次给出的代码似乎就是仅仅多加了一个“not”,是吗?

讯飞星火:是的,我添加了“not”关键字来反转start_success()的结果。这样,当start_success()返回False时,循环将继续执行。

南溪:
我感觉星火教授的回答很奇怪,跟我的问题似乎没有什么关联。

3 后记

我们感觉这个简单的API应该是可以实现的,可以想到的是:使用单例模式(将LimitedTime实现成一个单例class)加上记录函数的调用栈信息,来有效地区分和判别当前循环,来判断当前循环的执行是否超时,以实现上述这种简单的调用形式;

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

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

相关文章

Java-获取文件

import java.io.File; public class demo02 {public static void main(String[] args) {//每个目录都是一个File类型的对象//字符串类型的文件路径String path"D:\\音乐";File dirnew File(path);//获取目录相关的信息System.out.println("目录的路径&#xff1…

React18源码: React中的LanePriority和SchedulerPriority

优先级区别和联系 在源码中,3种优先级位于不同的js文件,是相互独立的注意: LanePriority 和 SchedulerPriority 从命名上看,它们代表的是优先级ReactPriorityLevel 从命名上看,它代表的是等级而不是优先级 它用于衡量…

层序遍历+小根堆,LeetCode 2476. 二叉搜索树最近节点查询

目录 一、题目 1、题目描述 2、接口描述 3、原题链接 二、解题报告 1、思路分析 2、复杂度 3、代码详解 一、题目 1、题目描述 给你一棵二叉树的根节点 root 和一个正整数 k 。 树中的 层和 是指 同一层 上节点值的总和。 返回树中第 k 大的层和(不一定不同…

SORA技术报告

文档链接:https://openai.com/research/video-generation-models-as-world-simulators 文章目录 Video generation models as world simulatorsTurning visual data into patchesVideo compression networkSpacetime latent patchesScaling transformers for video …

C# If与Switch的区别

在 switch 语句中使用表达式比较时,编译器会生成一个查找表,其中包含所有表达式的值和对应的 case 标签。因此,与使用常量或字面量比较相比,使用表达式比较可能会略微降低性能。 只有当 switch 语句中的所有 case 标签都使用常量或…

Web 前端 UI 框架Bootstrap简介与基本使用

Bootstrap 是一个流行的前端 UI 框架,用于快速开发响应式和移动设备优先的网页。它由 Twitter 的设计师和工程师开发,现在由一群志愿者维护。Bootstrap 提供了一套丰富的 HTML、CSS 和 JavaScript 组件,可以帮助开发者轻松地构建和定制网页和…

【Qt学习】QRadioButton 的介绍与使用(性别选择、模拟点餐)

文章目录 介绍实例使用实例1(性别选择 - 单选 隐藏)实例2(模拟点餐,多组单选) 相关资源文件 介绍 这里简单对QRadioButton类 进行介绍: QRadioButton 继承自 QAbstractButton ,用于创建单选按…

HTTP攻击,该怎么防护

一般网络世界里为人们所熟知的DDoS攻击,多数是通过对带宽或网络计算资源的持续、大量消耗,最终导致目标网络与业务的瘫痪;这类DDOS攻击,工作在OSI模型的网络层与传输层,利用协议特点构造恶意的请求载荷来达成目标资源耗…

2024年【起重机司机(限桥式起重机)】考试报名及起重机司机(限桥式起重机)证考试

题库来源:安全生产模拟考试一点通公众号小程序 起重机司机(限桥式起重机)考试报名考前必练!安全生产模拟考试一点通每个月更新起重机司机(限桥式起重机)证考试题目及答案!多做几遍,其实通过起重机司机(限桥式起重机)作业考试题库…

修复Microsoft Edge WebView2无法安装的问题

修复Microsoft Edge WebView2无法安装的问题 场景解决方案 场景 系统:win11 电脑:联想14 前提:使用Geek Uninstaller强制删除了Microsoft Edge WebView2 同时下载了clash verge。 发现根本无法运行(点击了无任何反应且图标颜色…

【深度学习笔记】3_6 代码实现softmax-regression

注:本文为《动手学深度学习》开源内容,仅为个人学习记录,无抄袭搬运意图 3.6 softmax回归的从零开始实现 这一节我们来动手实现softmax回归。首先导入本节实现所需的包或模块。 import torch import torchvision import numpy as np import…

QT Widget自定义菜单

此文以设置QListWidget的自定义菜单为例,其他继承于QWidget的类也都可以按类似的方法去实现。 1、ui文件设置contextMenuPolicy属性为CustomContextMenu 2、添加槽函数 /*** brief onCustomContextMenuRequested 右键弹出菜单* param pos 右键的坐标*/void onCusto…

十一、Qt数据库操作

一、Sql介绍 Qt Sql模块包含多个类,实现数据库的连接,Sql语句的执行,数据获取与界面显示,数据与界面直接使用Model/View结构。1、使用Sql模块 (1)工程加入 QT sql(2)添加头文件 …

2023年的AI模型学习/部署/优化

可以的话,github上给点一个小心心,感谢观看。 LDC边缘检测的轻量级密集卷积神经网络: meiqisheng/LDC (github.com)https://github.com/meiqisheng/LDC segment-anything分割一切的图像分割算法模型: meiqisheng/segment-anyt…

群晖NAS DSM7.2.1安装宝塔之后无法登陆账号密码问题解决

宝塔的安装就不在这赘述了,只说下,启动之后默认账号密码无法登陆的问题。 按照上面给出的账号密码,无法登陆 然后点忘记密码,由于是docker安装的,根目录下没有/www/server/panel 。 也没有bt命令 要怎么修改呢。 既然…

【Java程序设计】【C00283】基于Springboot的校园志愿者管理系统(有论文)

基于Springboot的校园志愿者管理系统(有论文) 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的校园志愿者管理系统 本系统分为系统功能模块、管理员功能模块以及志愿者功能模块。 系统功能模块:用户进入到系统…

应用中如何将单数据库升级为集群【数据库集群】【MySQL集群模式】

MySQL集群架构搭建以及多数据源管理实战 应用中如何将单数据库升级为集群1、搭建MySQL集群,实现服务和数据的高可用1>搭建基础MySQL服务。​ 2、启动MySQL服务​ 3、连接MySQL 2>搭建MySQL主从集群1》配置master服务2》配置slave从服务3》主从集群测试4》全库…

Github 2024-02-23 开源项目日报 Top10

根据Github Trendings的统计,今日(2024-02-23统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量非开发语言项目4Python项目3TypeScript项目1HTML项目1Dart项目1Rust项目1 从零开始构建你喜爱的技术 创建周…

智胜未来,新时代IT技术人风口攻略-第七版(弃稿)

文章目录 前言鸿蒙生态科普调研人员画像角色先行结论 - 市场下的增量蛋糕高校助力鸿蒙 - 掀起鸿蒙教育热潮高校鸿蒙课程开设占比 - 巨大需求背后是矛盾冲突教研力量并非唯一原因 - 看重教学成果复用与效率 企业布局规划 - 多元市场前瞻视野全盘接纳仍需一段时间 - 积极正向的一…

【新手易错点】golang中byte和rune

1 总体区别 在Golang中,byte和rune是两种不同类型的数据。简单来说,byte是一个8位的无符号整数类型,而rune则是一个32位的Unicode字符类型。 Byte: 在Golang中,byte类型实际上是uint8的别名,它用来表示8位的无符号整…