为什么我的脚本试图解压缩尚未下载​​的文件?

时间:2017-01-10 17:37:19

标签: python python-3.x zipfile

我有一个Python 3脚本,我写的是做三件事:

1)确定应下载哪些Retrosheets数据文件 2)创建wget命令以检索文件并下载它们 3)下载文件后解压缩。

在Python控制台中测试每个函数时,我没有任何问题。但是,当我尝试自动完成所有操作时,我得到以下输出:

    Start Decade: 1930
    End Decade: 1950
    Creating wget commands...
    Commands created...
    Downloaded 3 files.
    Unzipping files...
    Traceback (most recent call last):
      File "import_pbp.py", line 54, in <module>
        unzip_data(decade_files)
      File "import_pbp.py", line 39, in unzip_data
        with zipfile.ZipFile('zip' + file, 'r') as zip_ref:
      File      "/usr/local/Cellar/python3/3.5.2_1/Frameworks/Python.framework/Versions/3.5 /lib/python3.5/zipfile.py", line 1009, in __init__
    self.fp = io.open(file, filemode)
    FileNotFoundError: [Errno 2] No such file or directory: 'zip1930seve.zip'

将此输出后的文件下载到控制台。这似乎表明解压缩功能在下载文件之前正在运行。在调用解压缩函数之前,如何确保下载文件?代码如下:

下载功能:

# define function to execute the download commands
def download_data(commands):
    for command in commands:
        os.popen(command)
    print('Downloaded ' + str(len(commands)) + ' files.')

解压缩功能:

# Unzip the data files into the 'unparsed' folder.
def unzip_data(file_list):
    print('Unzipping files...')
    for file in file_list:
        with zipfile.ZipFile('zip' + file, 'r') as zip_ref:
            zip_ref.extractall('unparsed/')
        print(file + ' unzipped')
    print('All files unzipped...')
编辑:我查看了回复in this thread,但它没有完全解释我需要的东西,就像下面的德拉尼所做的那样。它们是相似的,但就我的目的而言,不同。特别是因为这个问题已经有6年了,我猜这个语言可能会有很大的变化。

编辑2:删除非必要代码以缩短帖子。

1 个答案:

答案 0 :(得分:1)

os.popen不等待进程完成,因此您立即启动所有命令,然后在完成之前尝试解压缩。由于您没有阅读从stdout返回的os.popen管道,因此如果输出管道填满,您也会冒着程序挂起的风险。

subprocess模块有几个用于调用程序的函数。假设您确实希望所有命令并行运行,并且您只想丢弃命令中的任何输出数据,则可以重新实现该功能

import subprocess as subp
import os

# define function to execute the download commands and unzip
def download_data(commands):
    procs = []
    for command in commands:
        procs.append(subp.Popen(command, shell=True, 
            stdout=open(os.devnull, 'wb')))
    for proc in procs:
        proc.wait()
    print('Downloaded ' + str(len(commands)) + ' files.')