装饰一个改变文件打开方式的读函数

Decorate a read function that changes the way of opening a file

我有以下功能

def read_tower(path_to_file):

    with open(path_to_file,'r') as f:

        for text in f:

            text_line = text.strip().split(" ")

我的想法是使用装饰器来更改该功能,这样我就可以从像

这样的 zip 文件夹中读取文件
with zipfile.ZipFile(Path(zip_filename)) as z:
    for filename in z.namelist():
        if re.search(r'.*\.mlm',filename):
            #with z.open(filename,mode="r") as f:
            data = read_tower(f)

所以基本上我想装饰 read_tower 所以我可以使用 z.open 而不是 打开

我对装饰器还很陌生。谢谢

要使用装饰器做到这一点,您可以将任何文件类型的 ContextManager 注入到读取、写入(或您需要的任何其他处理)逻辑中,如下所示:

def reader(func):
    def wrap(*args, **kwargs):
        with func(*args, **kwargs) as f:
            for text in f:
                text_line = text.strip().split(" ")
            ...      
    return wrap

@reader
def file_reader(*args, **kwargs):
    return open(*args, **kwargs)

@reader
def zipfile_reader(z, *args, **kwargs):
   return z.open(*args, **kwargs)

file_content = file_reader(<path>, <mode>)
zipfile_content = zipfile_reader(zipfile_obj, <filename>, <extra_args>)

但我建议简单地将 read_tower 中的通用逻辑提取到一个单独的函数中:

def read_file_content(file):
    for text in f:
        text_line = text.strip().split(" ")
    ...

文件使用情况:

with open('..path', mode) as f:
    read_file_content(f)

zip 文件用法:

with zipfile.ZipFile(Path(zip_filename)) as z:
    for filename in z.namelist():
        if re.search(r'.*\.mlm',filename):
            with z.open(filename,mode="r") as f:
                read_file_content(f)

注意:这里的代码只是为了提供思路,并不是完全有效的代码。