Рубрики
Без рубрики

TIL: Что происходит при использовании диспетчера контекстов вне его с

На днях я узнал две вещи о контекстных менеджерах. Первый – это то, что переменная, создает … Tagged с Python, сегодня.

На днях я узнал две вещи о контекстных менеджерах. Первым является то, что переменная, созданная при использовании с ... как x существуют вне контекста. Это не удивительно, я просто никогда не пробовал это раньше. Во -вторых, то, что происходит при вызове метода на диспетчете контекста за пределами с -Поджнение, действительно зависит от реализации. Что по какой -то причине удивило меня намного больше, чем это должно. В любом случае, давайте пойдем в то, как я наткнулся на это.

Итак, на работе я наткнулся на какой -то код, который я был удивлен, работал вообще. Это связано с использованием Flask.testing. FlaskClient Как менеджер контекста, который показан в учебном пособии: https://flask.palletsprojects.com/en/1.1.x/testing/ Анкет Я не могу поделиться кодом Но я воссоздаю сценарий с минимальным примером.

Для начала у меня есть пример приложения Flask my_flask_app.py , который содержит код:

from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello_world():
    return "Hello World!"

Я также создал файл test_app.py , который я буду использовать для небольшого теста для приложения. Файл выглядит так:

import pytest
import my_flask_app

def test_helloworld():
    with my_flask_app.app.test_client() as client:
        pass
    resp = client.get("/")
    assert resp.get_data(as_text=True) == "Hello World!"

Если вы знаете, как работают менеджеры контекста, вы, вероятно, можете увидеть проблему. Я использую Клиент Контекстная переменная вне контекста. Я использую Пасс Заявление здесь, но на самом деле это был еще какой -то код настройки. Это была легкая ошибка, имея неправильный уровень отступления на одной строке кода. Что было так удивительно, так это то, что тест на самом деле работает.

Это заставило меня копаться, и я наткнулся на этот вопрос Stackoverflow: https://stackoverflow.com/questions/52028124/why-use-flasks-app-test-client-over-requests-session-for-testing Анкет Итак, здесь происходит то, что менеджер контекста дает вам доступ к Stack-Stack в контексте, но это не влияет на фактическое общение. Поэтому, когда вы выходите из контекста, клиент по -прежнему работал, как и ожидалось, для того, что нам нужно в тесте.

Я мог бы противопоставить это с наиболее распространенным менеджером контекста, файл возвращался из открытым . Итак, что мы обычно делаем, так это:

with open("my_file.txt", "r") as f:
    f.read()

Если бы мы сделали чтение вне блока контекста, как это:

with open("my_file.txt", "r") as f:
    pass
f.read()

Тогда мы получаем ValueError: операция ввода/вывода в закрытом файле. , что ожидается как идея этого контекстного диспетчера, заключается в автоматическом закрытии файла после завершения.

Подводя итог, что я беру с собой из этого открытия. Вместо слепого использования диспетчера контекста, постарайтесь понять, какой контекст он на самом деле устанавливает. Кроме того, я думаю, что это может быть уроком, когда вы разрабатываете собственных контекстных менеджеров. Убедитесь, что намерение хорошо задокументировано, и подумайте о том, как вы хотите, чтобы объект вел себя при использовании вне контекста. Возможно, будет выпущена ошибка, потому что был выпущен ресурс. В этом случае убедитесь, что сообщение об ошибке является ясным и простым для понимания.

Оригинал: “https://dev.to/fronkan/til-what-happens-when-using-the-context-manager-outside-its-with-statement-1c7c”