Python 컨 텍스트 관리자 와 with 블록 상세 설명

컨 텍스트 관리자 와 with 블록,구체 적 인 내용 은 다음 과 같 습 니 다.
컨 텍스트 관리자 대상 이 존재 하 는 목적 은 with 문 구 를 관리 하 는 것 입 니 다.마치 교체 기의 존재 가 for 문 구 를 관리 하기 위 한 것 과 같 습 니 다.
with 문장의 목적 은 try/finally 모델 을 간소화 하 는 것 이다.이 모드 는 코드 가 실 행 된 후에 특정한 작업 을 수행 하도록 하 는 데 사 용 됩 니 다.그 코드 가 이상,return 구문 또는 sys.exit()호출 로 중단 되 더 라 도 지정 한 작업 을 수행 합 니 다.finally 자구 의 코드 는 보통 중요 한 자원 을 방출 하거나 임시 변 경 된 상 태 를 복원 하 는 데 사 용 됩 니 다.
==컨 텍스트 관리자 프로 토 콜 은 enter 와 exit 두 가지 방법 을 포함 합 니 다.with 문장 이 실 행 될 때 상하 문 관리자 대상 에서 enter 방법 을 호출 합 니 다.with 문 구 를 실행 한 후 컨 텍스트 관리자 대상 에서 exit 방법 을 호출 하여 finally 자구 의 역할 을 합 니 다.
==with 뒤의 표현 식 을 실행 하여 얻 은 결 과 는 컨 텍스트 관리자 대상 입 니 다.대상 변수 에 값 을 연결 하 는 것(as 자구)은 컨 텍스트 관리자 대상 에서 enter 방법 을 호출 한 결과 입 니 다.with 문장의 as 자 구 는 선택 할 수 있 습 니 다.open 함수 에 있어 서 는 파일 의 인용 을 얻 기 위해 as 자 구 를 추가 해 야 합 니 다.그러나 일부 컨 텍스트 관리 자 는 사용자 에 게 제공 할 수 있 는 유용 한 대상 이 없 기 때문에 None 으로 돌아 갑 니 다.

with open('mirror.py') as fp:
  ...
사용자 정의 컨 텍스트 클래스:

class A:
  def __init__(self, name):
    self.name = name

  def __enter__(self):
    print('enter')
    return self.name

  def __exit__(self, exc_type, exc_val, exc_tb):
    print('gone')

with A('xiaozhe') as dt:
  print(dt)
contextlib 모듈
contextlib 모듈 에는 클래스 와 다른 함수 가 있어 서 사용 범위 가 더욱 넓 습 니 다.
closing:대상 이 close()방법 을 제 공 했 지만 enter/exit 프로 토 콜 이 실현 되 지 않 았 다 면 이 함 수 를 사용 하여 상하 문 관리 자 를 구축 할 수 있 습 니 다.
suppress:지정 한 이상 한 컨 텍스트 관리 자 를 임시로 무시 합 니 다.
@contextmanager:==이 인 테 리 어 는 간단 한 생 성기 함 수 를 컨 텍스트 관리자 로 바 꿉 니 다.
ContextDecorator:클래스 기반 컨 텍스트 관리 자 를 정의 하 는 기본 클래스 입 니 다.이 컨 텍스트 관리 자 는 함수 장식 에 도 사용 할 수 있 으 며,관 리 된 컨 텍스트 에서 전체 함 수 를 실행 할 수 있 습 니 다.
ExitStack:이 컨 텍스트 관리 자 는 여러 컨 텍스트 관리자 에 들 어 갈 수 있 습 니 다.with 블록 이 끝 날 때 ExitStack 은 후진 이 먼저 나 오 는 순서에 따라 스 택 의 각 컨 텍스트 관리자 의 exit 방법 을 호출 합 니 다.
==가장 광범 위 하 게 사용 되 는 것 은@contextmanager 장식 기 이 므 로 각별히 주의해 야 합 니 다.이 장식 기 는 교체 와 상 관 없 이 yield 문 구 를 사용 해 야 하기 때문에 사람 을 현혹 시 키 는 면도 있다.
@contextmanager 사용 하기
@contextmanager 장식 기 는 컨 텍스트 관리 자 를 만 드 는 모델 코드 의 양 을 줄 일 수 있 습 니 다.완전한 클래스 정의 enter 와 exit 방법 을 만 들 지 않 고 하나의 yield 문 구 를 만 드 는 생 성 기 를 실현 하여 enter 방법 을 되 돌려 주 고 싶 은 값 을 만 듭 니 다.
@contextmanager 장식 을 사용 하 는 생 성기 에서 yield 문 구 는 함수 의 정의 체 를 두 부분 으로 나 누 는 역할 을 합 니 다.=yield 문 앞의 모든 코드 는 with 블록 이 시 작 될 때(즉 해석 기 가 enter 방법 을 호출 할 때)실 행 됩 니 다.yield 문 뒤의 코드 는 with 블록 이 끝 날 때(즉 exit 방법 을 호출 할 때)실 행 됩 니 다.=

import contextlib

@contextlib.contextmanager
def test(name):
  print('start')
  yield name
  print('end')

with test('zhexiao123') as dt:
  print(dt)
  print('doing something')
실현 원리
contextlib.contextmanager 장식 기 는 함 수 를 enter 와 exit 방법 을 실현 하 는 클래스 로 포장 합 니 다.클래스 의 이름 은GeneratorContextManager。
이 종류의 enter 방법 은 다음 과 같은 작용 을 한다.
1.생 성기 함 수 를 호출 하여 생 성기 대상 을 저장 합 니 다(여기 서 gen 이 라 고 합 니 다).
2.next(gen)를 호출 하여 yield 키워드 가 있 는 위치 로 실행 합 니 다.
3.next(gen)에서 나 온 값 을 with/as 문장의 목표 변수 에 연결 할 수 있 도록 되 돌려 줍 니 다.
with 블록 이 종 료 될 때 exit 방법 은 다음 과 같은 몇 가지 일 을 합 니 다.
1.이상 을 exc 에 게 전 달 했 는 지 확인type;있 으 면,gen.throw(exception)를 호출 하여,생 성기 함수 정의 체 에 yield 키 워드 를 포함 하 는 줄 에 이상 을 던 집 니 다.
2.그렇지 않 으 면 next(gen)를 호출 하여 생 성기 함수 정의 체 의 yield 문 구 를 계속 실행 합 니 다.
예외 처리
해석 기 이상 이 처리 되 었 음 을 알 리 기 위해 exit 방법 은 True 로 돌아 갑 니 다.이 때 해석 기 는 이상 을 억제 합 니 다.exit 방법 이 값 을 명시 적 으로 되 돌려 주지 않 으 면 해석 기 는 None 을 얻 고 위로 거품 이 생 깁 니 다.
@contextmanager 장식 기 를 사용 할 때 기본 적 인 행 위 는 반대 입 니 다.장식 기 가 제공 하 는 exit 방법 은 생 성기 에 보 내 는 모든 이상 이 처리 되 었 다 고 가정 하기 때문에 이상 을 억제 해 야 합 니 다.@contextmanager 에 이상 을 억제 하지 않 으 려 면 장 식 된 함수 에서 이상 을 다시 던 져 야 합 니 다.
위의 코드 에 bug 가 있 습 니 다.with 블록 에 이상 을 던 지면 Python 해석 기 는 이 를 캡 처 한 다음 test 함수 의 yield 표현 식 에서 다시 던 집 니 다.그러나 잘못된 코드 가 처리 되 지 않 아 test 함수 가 중 단 됩 니 다.
@contextmanager 장식 기 를 사용 할 때,yield 문 구 를 try/finally 구문 에 두 어야 합 니 다.컨 텍스트 관리자 의 사용자 가 with 블록 에서 무엇 을 할 지 영원히 모 르 기 때 문 입 니 다.

import contextlib

@contextlib.contextmanager
def test(name):
  print('start')

  try:
    yield name
  except:
    raise ValueError('error')
  finally:
    print('end')

with test('zhexiao123') as dt:
  print(dt)
  print('doing something')
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기