2017-01-10 3 views
0

私は3つのことを行うには、私が書いているのPython 3のスクリプトを持っていますそれらがダウンロードされた後のファイル。まだダウンロードされていないファイルを解凍しようとしているのはなぜですか?</p> <p>1)データファイルは 2をダウンロードすることになっているRetrosheetsを決定し)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' 

ファイルは、この出力後にコンソールにダウンロードされます。これは、ファイルがダウンロードされる前にunzip関数が実行されていることを示しているようです。解凍機能が呼び出される前にファイルがダウンロードされていることを確認するにはどうすればよいですか?以下のコード:

ダウンロード機能:

# 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に見えたが、それはかなりtdelaneyは下記行ったように私が必要かを説明しませんでした。彼らは似ていますが、私の目的では違います。特に、その質問は6歳であり、私はそれ以降、言語に大きな変化があったと推測しています。

編集2:投稿を短縮するために必須ではないコードを削除しました。

+0

可能性のある重複したように、その機能を再実装したと仮定すると。コマンドが完了するまで待つ(http://stackoverflow.com/questions/2837214/python-popen-command-wait-until-the-command-is-finished) – glibdud

+0

'os.popen()'コマンドは、終了するまで待ってから戻る。 – glibdud

答えて

1

os.popenプロセスが完了するのを待たずに、すぐにすべてのコマンドを起動してから、実行前に解凍を試みてください。 os.popenから返されたstdoutパイプを読み取らないので、出力パイプがいっぱいになると、プログラムがハングする危険があります。

subprocessモジュールには、プログラムを呼び出すためのいくつかの関数があります。あなたが本当にすべてのコマンドが並列で実行したいですし、あなただけのコマンドから任意の出力データを破棄することを、あなたは[Pythonのpopenのコマンドの

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.') 
+0

ありがとう!これは私のニーズに正確に働きます。なぜ2番目のforループが必要ですか?それは、コマンドがその上のforループで実行された後、各サブプロセスが完了していることを確認するだけですか? – JJAJ

+1

終了ステータスが読み取られるまでプロセスはプロセステーブルに残ります...ゾンビプロセス。プロセスが完了するのを待つか、存在しないファイルを解凍して戻ってくるのを待つだけでなく、自分のゾンビの黙示録をシステム上で避けるために呼び出す必要があります。 – tdelaney

+0

以前に解凍を開始するコードを書き直すことができます。おそらくサブプロセスとキューごとに1つのスレッド。各作業者は1つのコマンドを実行し、完了を待って、.zipファイルをキューに入れて、リスナーが消費するようにします。 – tdelaney

関連する問題

 関連する問題