【问题标题】:Setting a limit for running time with a Python 'while' loop使用 Python 'while' 循环设置运行时间限制
【发布时间】:2016-11-22 14:18:25
【问题描述】:

我有一些关于在 Python 中设置最长运行时间的问题。事实上,我想使用 pdfminer 将 PDF 文件转换为 .txt。问题是很多时候,一些文件无法解码并且需要很长时间。所以我想设置time.time() 将每个文件的转换时间限制为20秒。另外,我是在windows下运行的,所以无法使用信号功能。

我成功地使用pdfminer.convert_pdf_to_txt() 运行转换代码(在我的代码中它是“c”),但我无法将time.time() 集成到while 循环中。在我看来,在下面的代码中,while 循环和time.time() 不起作用。

总之,我想:

  1. 将 PDf 文件转换为 .txt 文件

  2. 每次转换的时间限制为 20 秒。如果超时,抛出异常并保存一个空文件

  3. 将所有txt文件保存在同一个文件夹下

  4. 如果有任何异常/错误,仍然保存文件,但内容为空。

这是当前代码:

import converter as c
import os
import timeit
import time

yourpath = 'D:/hh/'

for root, dirs, files in os.walk(yourpath, topdown=False):

    for name in files:

        t_end = time.time() + 20

        try:
            while time.time() < t_end:

                c.convert_pdf_to_txt(os.path.join(root, name))

                t = os.path.split(os.path.dirname(os.path.join(root, name)))[1]
                a = str(os.path.split(os.path.dirname(os.path.join(root, name)))[0])

                g = str(a.split("\\")[1])
                with open("D:/f/" + g + "&" + t + "&" + name + ".txt", mode="w") as newfile:
                    newfile.write(c.convert_pdf_to_txt(os.path.join(root, name)))
                    print "yes"

            if time.time() > t_end:

                print "no"

                with open("D:/f/" + g + "&" + t + "&" + name + ".txt", mode="w") as newfile:
                    newfile.write("")

        except KeyboardInterrupt:
           raise

        except:
            for name in files:
                t = os.path.split(os.path.dirname(os.path.join(root, name)))[1]
                a = str(os.path.split(os.path.dirname(os.path.join(root, name)))[0])

                g = str(a.split("\\")[1])
                with open("D:/f/" + g + "&" + t + "&" + name + ".txt", mode="w") as newfile:
                    newfile.write("")

【问题讨论】:

  • 一个有用的链接。 stackoverflow.com/questions/13293269/…
  • @Stormvirux 是的,我在完成上述代码之前阅读了这篇文章......我仍然无法弄清楚如何集成到我的代码中;(
  • @SXC88 - 刚刚完成我的回答,希望对您有所帮助!
  • 没有任何版本可以工作,因为这里没有任何东西会中断持续时间超过 20 秒的转换。
  • @pvg - 你是什么意思?

标签: python while-loop time-limiting


【解决方案1】:

你的方法不对。

您定义结束时间并如果当前时间戳低于结束时间戳,则立即进入while 循环(将始终为True)。所以进入了while 循环,你就卡在了转换函数上。

我建议使用 signal 模块,它已经包含在 Python 中。它允许您在n 秒后退出函数。一个基本的例子可以在this Stack Overflow answer看到。

你的代码应该是这样的:

return astring
import converter as c
import os
import timeit
import time
import threading
import thread

yourpath = 'D:/hh/'

for root, dirs, files in os.walk(yourpath, topdown=False):
    for name in files:
        try:
            timer = threading.Timer(5.0, thread.interrupt_main)
            try:
                c.convert_pdf_to_txt(os.path.join(root, name))
            except KeyboardInterrupt:
                 print("no")

                 with open("D:/f/" + g + "&" + t + "&" + name + ".txt", mode="w") as newfile:
                     newfile.write("")
            else:
                timer.cancel()
                t = os.path.split(os.path.dirname(os.path.join(root, name)))[1]
                a = str(os.path.split(os.path.dirname(os.path.join(root, name)))[0])
                g = str(a.split("\\")[1])

                print("yes")

                with open("D:/f/" + g + "&" + t + "&" + name + ".txt", mode="w") as newfile:
                    newfile.write(c.convert_pdf_to_txt(os.path.join(root, name)))

        except KeyboardInterrupt:
           raise

        except:
            for name in files:
                t = os.path.split(os.path.dirname(os.path.join(root, name)))[1]
                a = str(os.path.split(os.path.dirname(os.path.join(root, name)))[0])

                g = str(a.split("\\")[1])
                with open("D:/f/"+g+"&"+t+"&"+name+".txt", mode="w") as newfile:
                    newfile.write("")

只为未来:四个空格缩进,空格不要太多;)

【讨论】:

  • 您好,感谢您的评论!但问题是我使用的模块 pdfminer 只能在 python 2.X 下使用,所以我认为这里没有可用的信号函数(它实际上总是抛出错误)。此外,使用您的代码会弹出一条错误消息,并指示“除了 KeyboardInterrupt”存在语法错误...我很困惑...;((
  • @SXC88 - 抱歉,我的缩进有误。现在已经修好了。 signal 模块在 Python 2 下也可用:docs.python.org/2/library/signal.html。请再次运行,告诉我语法错误是否消失以及您对信号模块有什么错误。
  • 比你!但它总是向我抛出这条消息“第 14 行,在 signal.signal(signal.SIGALRM, timeout_handler) AttributeError: 'module' object has no attribute 'SIGALRM'” ...
  • 嗯,好的。所以它不是信号模块不可用,而是一个不存在的变量。等一下,我会解决的。
  • @SXC88 - 非常抱歉,但我想没有快速的解决方案。 signal 模块有一些仅适用于 Unix 的部分,我正在运行 Ubuntu。我假设你有 Windows,所以我无法为你测试它:( 但是,希望你现在知道你的代码出了什么问题,我至少可以提供一点帮助!
猜你喜欢
  • 2020-10-03
  • 1970-01-01
  • 1970-01-01
  • 2018-10-17
  • 2023-03-29
  • 2016-12-21
  • 1970-01-01
  • 1970-01-01
  • 2017-10-12
相关资源
最近更新 更多