0

簡単に言うと、特定の場所にあるすべてのサブフォルダーを循環し、3つの異なるファイルからいくつかの番号を収集しています。

def GrepData():
import glob as glob
import os as os

os.chdir('RUNS')
RUNSDir = os.getcwd()
Directories = glob.glob('*.*')
ObjVal = []
ParVal = []
AADVal = []

for dir in Directories:
    os.chdir(dir)
    (X,Y) = dir.split(sep='+')
    AADPath = glob.glob('Aad.out')
    ObjPath = glob.glob('fobj.out')
    ParPath = glob.glob('Par.out')

    try:
        with open(os.path.join(os.getcwd(),ObjPath[0])) as ObjFile:
            for line in ObjFile:
                ObjVal.append(list([X,Y,line.split()[0]]))
        ObjFile.close()
    except(IndexError):
        ObjFile.close()

    try:
        with open(os.path.join(os.getcwd(),ParPath[0])) as ParFile:
            for line in ParFile:
                ParVal.append(list([X,Y,line.split()[0]]))
        ParFile.close()
    except(IndexError):
        ParFile.close()
    try:
        with open(os.path.join(os.getcwd(),AADPath[0])) as AADFile:
            for line in AADFile:
                AADVal.append(list([X,Y,line.split()[0]]))
        AADFile.close()
    except(IndexError):
        AADFile.close()
    os.chdir(RUNSDir)

各ファイルを開くコマンドは、ブロックを除いてtryに配置されます。いくつかのケースでは、開かれるファイルが空になります。したがって、line.split()を追加すると、リストが空になるため、インデックスエラーが発生します。

ただし、このスクリプトを実行すると、次のエラーが発生します:「OSError:[Errno24]開いているファイルが多すぎます」

「withopen...」という言葉のアイデアは、使用後にファイルを閉じるのに注意を払うというものだという印象を受けました。明らかにそれは起こっていません。

だから私が求めているのは2つのことです:

  1. 答え:「オープンでの私の理解は正しいですか?」
  2. この問題を引き起こしているエラーを修正するにはどうすればよいですか?

(そして、はい、私はコードが正確にエレガントではないことを知っています。再利用される単一のオブジェクトであるべきを除いて、全体の試み-しかし、私はこのエラーを理解した後にそれを修正します)

4

2 に答える 2

1

try-exceptあなたの内側を次のwithように動かしてみてください:

with open(os.path.join(os.getcwd(),ObjPath[0])) as ObjFile:
    for line in ObjFile:
        try:
            ObjVal.append(list([X,Y,line.split()[0]]))
        except(IndexError): 
           pass

注:ファイルを手動で閉じる必要はありません。これwithが目的です。as osまた、同じ名前を使用している場合は、インポートで使用する必要はありません。

于 2013-02-20T17:42:51.107 に答える
0

「開いているファイルが多すぎる」とは、意味的に正しくないPythonコードを記述することとは関係がなく、with正しく使用しています。キーは、基盤となるオペレーティングシステムを指す「OSError」というエラーの一部です。

open()を呼び出すと、Pythonインタープリターがシステムコールを実行します。システムコールの詳細は、使用しているOSによって少し異なりますが、Linuxではこのコールはopen(2)です。オペレーティングシステムカーネルがシステムコールを処理します。ファイルが開いている間、システムファイルテーブルにエントリがあり、OSリソースを消費します。これは、ファイルが開いている間、事実上「スペースを占有している」ことを意味します。そのため、OSには、一度に開くことができるファイルの数に制限があります。

あなたの問題は、open()を呼び出している間、close()を十分に速く呼び出さないことです。ディレクトリ構造で、この上限に近づく可能性のある数千のファイルを一度に開く必要がある場合は、一時的に変更できます(少なくとも、Linuxでは、他のOSに慣れていないため、行きたくありません。プラットフォーム間でこれを行う方法についての詳細が多すぎます)。

于 2013-02-20T17:49:27.330 に答える