3

我想写一个python脚本来处理一些日志文件。该应用程序每周产生大约 1 GB 的日志,并在周末将这些日志压缩到每个大约 50 兆字节。

我不想分开处理 zip 文件和非压缩日志文件的代码,即我不希望if (zip) then (blah1) else (blah2)所有代码都在,理想情况下这样的检查应该只发生一次,其余代码应该是相同的。是否有任何方法/库可以统一 zip/普通文件,以便可以使用相同的代码来读取它们。

我不需要写。请注意,我在这里处理目录(和压缩目录),而不仅仅是单个文件,所以我需要能够在两者中移动。

4

2 回答 2

4

我的基本方法是抽象一个 zip 文件和一个目录,以便它们具有相似的接口。在这里,我选择考虑 zip 文件“规范”并简单地为目录实现zipfile'snamelist()open()方法。(这类似于 Mark Hildreth 的回答,只是我不是在设计一个全新的 API。)当然,如果需要,您可以实现更多。

工厂函数根据您给它的内容opencontainer()返回一个ZipFile实例或一个实例。Directory(您也可以只使用一种__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 回答