这是Windows环境下的python程序的一部分。我正在尝试执行以下操作: 从一个HTML,我想创建一个PDF,然后打开它:
#create the pdf os.system("start wkhtmltopdf.exe result.html %s%s" %(output_directory, pdf_document_name)) #open the current pdf os.system("start %s%s" %(output_directory, pdf_document_name))
问题是有时创建pdf的脚本速度较慢,所以我从终端收到错误,说没有这样名字的文件。
我想问一下,只有在创建成功并完成时才能打开pdf。我知道如何通过调用time.sleep()来做到这一点,但我认为这不太专业。
非常感谢,你D
答案 0 :(得分:2)
无论您使用哪种方法执行shell命令(subprocess,os.system等),都应该在尝试打开文件之前验证文件是否存在。然后,您可以在尝试打开延迟之前将延迟设置为File-Exists-Else-Wait-Repeat循环。 您可以使用os.path.exists():
执行此操作#create the pdf
os.system("start wkhtmltopdf.exe result.html %s%s" %(output_directory, pdf_document_name))
#loop until pdf exists, but add some timer to avoid endless repetition
maxiterations = 60
exists = False
for i in range(maxiterations):
if os.path.exists(os.path.join(output_directory, pdf_document_name)):
exists = True
break;
time.sleep(1)
#open the current pdf
if exists:
os.system("start %s%s" %(output_directory, pdf_document_name))
else:
print 'Could not find file %s to open' % os.path.join(output_directory, pdf_document_name)
另一个需要注意的是,这会引入一个安全漏洞,因为文件可能会在您验证它并打开它之间传递的时间内发生变化(例如,它可能已被恶意代码替换)。 处理此问题的另一种方法是尝试在try ... except ...块中打开它,但这并不能真正解决安全问题(文件可能在创建和尝试打开它之间被替换)
答案 1 :(得分:1)
我认为使用time.sleep()
并不存在“不专业”的问题。实际上,对于你建议的解决方案,最不专业(或者至少是Pythonic)的事情是使用os.system
。请改用subprocess
模块中的函数。在这种情况下,您可以使用subprocess.call
,等待程序在继续之前退出。例如,如果您在交互式解释器中执行此操作:
import subprocess, shlex
subprocess.call(shlex.split('sleep 5'))
你会看到Python在继续之前等待五秒钟sleep
完成。 (然后返回退出代码。)Shlex只需将命令行拆分为参数列表,供call
或subprocess
提供的其他几个函数和类使用。
>>> shlex.split("start wkhtmltopdf.exe result.html %s%s" %('out_dir/', 'pdf_name'))
['start', 'wkhtmltopdf.exe', 'result.html', 'out_dir/pdf_name']