我正在制作一个计算器,当您try 计算一个较高的数字(如9⁹⁹⁹⁹⁹⁹)来计算此问题时,代码冻结,我想设置一个超时,如果计算花费的时间超过3秒,结果就是"NaN". 计算结果的代码片段如下所示,但它不起作用.如果计算时间超过3秒,则不会取消该任务.

async def do_calculation(realcalculation, X, Y, A, B, C):
    try:
        result = str(numerize(sympy.sympify(realcalculation).subs(dict(X=X, Y=Y, A=A, B=B, C=C))))
    except:
        result = "NAN"
        raise
    return result

async def calculate(realcalculation, X, Y, A, B, C):
    loop = asyncio.get_running_loop()
    task = loop.create_task(do_calculation(realcalculation, X, Y, A, B, C))
    try:
        result = await asyncio.wait_for(task, timeout=3)
    except asyncio.TimeoutError:
        task.cancel()
        result = "NAN"
    return result

result = await calculate(realcalculation, X, Y, A, B, C)

推荐答案

对于这一点,真的没有一个好的解决方案.问题是,真正大的数字,那些不能以常规浮点型存储的数字,会自动切换到BigNum数学(每PEP 237个).虽然使用规则浮点数的算术运算是一种几乎恒定的时间运算,但BigNum数学运算通常需要多项式时间.所以,计算非常大的数字需要很长的时间.

你不能取消任务的原因是,在do_calculation中,你给asyncio一个取消它的机会是没有意义的.正如docs人所说,

当一项任务被取消时,下一次机会将在该任务中提高asyncio.CancelledError.

这个"机会"就在你await岁的时候.因为do_calculation永远不会因为某件事而变得await%,所以它永远不会被取消.

为了抵消这一点,我只需添加一个可以输入数字的上限.如果开头的数字太高,则返回NaN即可.因为在所有规格的系统上没有保证将其保持在3秒以下的上限,所以您需要试验什么是对您的机器最好的.

Python相关问答推荐

使用matplotlib pcolormesh,如何停止从一行绘制的磁贴连接到上下行?

NumPy中的右矩阵划分,还有比NP.linalg.inv()更好的方法吗?

如何使用Python中的clinicalTrials.gov API获取完整结果?

Pandas 填充条件是另一列

需要计算60,000个坐标之间的距离

如何标记Spacy中不包含特定符号的单词?

_repr_html_实现自定义__getattr_时未显示

将输入管道传输到正在运行的Python脚本中

将图像拖到另一个图像

使用Python更新字典中的值

driver. find_element无法通过class_name找到元素'""

如何并行化/加速并行numba代码?

为什么Django管理页面和我的页面的其他CSS文件和图片都找不到?'

如何将一组组合框重置回无 Select tkinter?

从一个df列提取单词,分配给另一个列

如何在FastAPI中替换Pydantic的constr,以便在BaseModel之外使用?'

使用polars. pivot()旋转一个框架(类似于R中的pivot_longer)

如何训练每一个pandaprame行的线性回归并生成斜率

如何编辑此代码,使其从多个EXCEL文件的特定工作表中提取数据以显示在单独的文件中

如何根据一定条件生成段id