3

いくつかのログ ファイルを処理する Python スクリプトを書きたいと思います。このアプリケーションは、1 週間に約 1 ギガバイトのログを生成し、週末にはこれらのログをそれぞれ約 50 メガバイトに圧縮します。

zip ファイルと圧縮されていないログ ファイルを処理するためのコードを分離する必要はありません。つまり、コード全体をすべて処理したくありませんif (zip) then (blah1) else (blah2)。理想的には、このようなチェックは 1 回だけ実行し、残りのコードは同じ。同じコードを使用してそれらを読み取ることができるように、zip/通常のファイルを統合する方法/ライブラリはありますか。

書き込みを行う必要はありません。ここでは、個々のファイルだけでなく、ディレクトリ (および圧縮されたディレクトリ) を扱っているため、両方を同じように移動できる必要があることに注意してください。

4

2 に答える 2

4

私の基本的なアプローチは、zipファイルとディレクトリを抽象化して、それらが同様のインターフェイスを持つようにすることです。ここでは、zipファイルを「正規」と見なし、ディレクトリzipfilenamelist()open()メソッドを単純に実装することを選択しました。(これは、Mark Hildrethの回答に似ていますが、まったく新しいAPIを設計しているわけではありません。)もちろん、必要に応じてさらに実装することもできます。

ファクトリ関数は、指定した内容に応じて、インスタンスまたはインスタンスのopencontainer()いずれかを返します。(これを行うには、上のメソッドを使用することもできます。)ZipFileDirectory__new__()Directory

namelist()次に、コンテナのopen()メソッドを使用して、コンテナ内のファイルを繰り返して開くことができます。その時点でfile、zipファイルからオブジェクトまたはファイルのようなオブジェクトがあり、これらのAPIは設計上すでに類似しています。

import zipfile, os

class Directory(object):
    def __init__(self, path):
        self.path = path
    def namelist(self):
        return os.listdir(self.path)
    def open(self, name):
        return open(os.path.join(self.path, name))

def opencontainer(path):
    if zipfile.is_zipfile(path):
        return zipfile.ZipFile(path)
    return Directory(path)

container = opencontainer(path)
for logname in container.namelist():
    logtext = container.open(logname).read()

これはソリューションの非常に大まかなスケッチであり、おそらくいくつかの強化されたエラー処理とリソース管理が必要です(コンテキストマネージャーはファイルが閉じられることを確認するのに意味があるかもしれません)。

于 2012-06-12T05:37:33.917 に答える
2

これを行うライブラリはわかりませんが、書くのはそれほど難しいことではありません。基本的に、あなたはあなたが言うように行います:最初に一度チェックし、そしてあなたが見つけたファイルのタイプに基づいて反応します。「戦略パターン」は、プログラミングで一般的なパターンであり、次のようになります。

class ZipFileAccessStrategy(object):
    def __init__(self, filename):
         ...open the zipfile...

    def get_file(self, filename):
         ...get a file from the archive....

    def get_files(self, directory):
         ...get a list of all files in a directory in the zip file...

class DirectoryAccessStrategy(object):
    def __init__(self, directory):
         ...store the name of the directory...

    def get_file(self, filename):
         ...get a file relative to this directory....

    def get_files(self, directory):
         ...get a list of all files in a specific path relative to the directory...

filename = '...'
if is_zipfile(filename):
    strategy = ZipFileAccessStrategy(filename)
else:
    strategy = DirectoryAccessStrategy(filename)

# Now we can access whether Zip File or Directory using a common interface
file_list = strategy.get_files('/')
f = strategy.get_file(file_list[0])

私はいくつかの実装の詳細を無視しました、そして同様に心配するべきファイルの適切な開閉があります。ただし、これで一般的な考え方が得られることを願っています。

于 2012-06-12T05:20:27.097 に答える