python 中的上下文管理器和辅助函数

context manager and helper function in python

我有几个使用上下文管理器的函数:

def f1():
    with open("test.txt","r+") as f:
        f.write("common Line")
        f.write("f1 Line")

def f2():
    with open("test.txt","r+") as f:
        f.write("common Line")
        f.write("f2 Line")

def f3():
    with open("test.txt","r+") as f:
        f.write("common Line")
        f.write("f3 Line")

这些函数有一些共同点。所以我想添加一个辅助函数。像这样

def helperF():
    with open("test.txt","r+") as f:
        f.write("common Line")

然后以某种方式从我的 f1、f2、f3 函数调用它以使代码变干。

但我不太确定在这种情况下如何处理上下文管理器。以下将不起作用,因为在调用函数时 f 已经关闭:

def f1():
    commonHelper()
    f.write("f1 Line")

def f2():
    commonHelper()
    f.write("f2 Line")

def f3():
    commonHelper()
    f.write("f3 Line")

如果这三个函数每个都向文件写入相当多的内容,我建议重构,以便它们 return 一个要写入的字符串列表,而不是让多个函数直接写入文件.

def write_with_common_header(lines):
    with open("test.txt", "r+") as f:
        f.write("common Line")
        for line in lines:
            f.write(line)

def f1():
    return ["f1 Line"]

def f2():
    return ["f2 Line"]

def f3():
    return ["f3 Line"]

# usage example:
write_with_common_header(f2())

如果每个函数 return 生成的列表总是相同的,那么它们甚至不需要是函数;您可以将它们声明为列表。


在更一般的情况下,上下文管理器不一定是一个文件,并且单独的函数不仅仅是调用一个方法,那么我们不能只将它们作为数据传递,但同样可以应用技术:让 write_with_common_header 函数接受一个参数,这样它的行为就可以被参数化。为了完全通用,参数应该是一个函数,它接受对托管资源的引用 f.

def common_helper(callback):
    with open("test.txt", "r+") as f:
        f.write("common Line")
        callback(f)

def f1(f):
    f.write("f1 Line")

def f2(f):
    f.write("f2 Line")

def f3(f):
    f.write("f3 Line")

# usage example: 
common_helper(f2)