менеджер контекста и вспомогательная функция в python - PullRequest
4 голосов
/ 13 января 2020

У меня есть несколько функций, которые используют менеджер контекста:

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, чтобы сделать код DRY.

Но я не совсем уверен, как поступить с менеджером контекста в этой ситуации. Следующее не будет работать, потому что к моменту вызова функции f уже закрыта:

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

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

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

1 Ответ

3 голосов
/ 13 января 2020

Если три функции записывают в файл совсем немного, я бы рекомендовал рефакторинг, чтобы они возвращали список строк для записи, вместо того, чтобы иметь несколько функций, которые записывают непосредственно в файл.

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())

Если списки, возвращаемые каждой функцией, всегда будут одинаковыми, то нет необходимости, чтобы они даже были функциями; Вы можете просто объявить их как списки.


В более общем случае, когда менеджер контекста не обязательно является файлом, а отдельные функции выполняют больше, чем просто вызов одного метода, тогда мы можем не просто передавать их как данные, но можно применить тот же метод: заставить функцию 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...