Python 의 컨 텍스트 관리자 와 else 블록 을 깊이 학습 합 니 다.
본 고 는 주로 Python 컨 텍스트 관리자 와 else 블록 에 관 한 내용 을 소개 하고 참고 학습 을 제공 합 니 다.다음은 더 이상 말 하지 않 겠 습 니 다.상세 한 소 개 를 해 보 겠 습 니 다.
시작 하기 전에 다음 말 을 살 펴 보 자.
결국 컨 텍스트 관리 자 는 서브루틴 자체 만큼 중요 할 수 있 습 니 다.현재,우 리 는 컨 텍스트 관리자 의 모피 만 알 고 있 습 니 다.Basic 언어 는 with 문구 가 있 고,많은 언어 가 있 습 니 다.그러나 각종 언어 에서 with 문장의 역할 이 다 르 고 간단 한 일 을 합 니 다.점 호 를 계속 사용 하여 속성 을 찾 는 것 을 피 할 수 있 지만 일 하기 전에 준비 하고 사후 청 소 를 하지 않 습 니 다.이름 이 같다 고 생각 하지 마라,작용 도 같다 는 것 을 의미한다.with 문 구 는 매우 일어나 지 않 는 특성 이다.
――Raymond Hettinger
웅변 적 인 파 이 썬 보도 자
이것 을 먼저 하고 저것 을 하 세 요:if 문장 이외 의 else 블록
이 언어 특성 은 비밀 은 아니 지만 중시 되 지 않 았 다.else 자 구 는 if 구문 뿐만 아니 라 for,while,try 구문 에서 도 사용 할 수 있다.for/else,while/else 와 try/else 의 의미 관 계 는 밀접 하지만 if/else 와 차이 가 크다.처음에 else 라 는 단어의 뜻 은 이러한 특성 에 대한 이 해 를 방해 하 였 으 나 결국 나 는 습관 이 되 었 다.
else 자구 의 행동 은 다음 과 같다.
for
for 순환 이 끝 났 을 때 만(즉,for 순환 이 break 구문 에 의 해 중단 되 지 않 았 음)else 블록 을 실행 합 니 다.
while
while 순환 이 가짜 값 으로 종료 되 었 을 때(즉,while 순환 이 break 구문 에 의 해 중단 되 지 않 았 음)else 블록 을 실행 합 니 다.
try
try 블록 에 이상 이 없 을 때 만 else 블록 을 실행 합 니 다.공식 문서https://docs.python.org/3/reference/compound_stmts.html는 또"else 자구 가 던 진 이상 은 앞의 except 자구 로 처리 되 지 않 는 다"고 지적 했다.
주의:
모든 상황 에서 이상 하거나 return,break 또는 continue 문 구 를 통 해 제어 권 이 복합 문장의 메 인 블록 밖으로 넘 어가 면 else 자구 도 건 너 뜁 니 다.
이 문장 들 에서 else 자 구 를 사용 하면 코드 를 쉽게 읽 을 수 있 고 번 거 로 움 을 줄 일 수 있 으 며 제어 표 지 를 설정 하거나 추가 적 인 if 문 구 를 추가 하지 않 아 도 된다.
다음 코드 세 션 과 같이 else 자 구 를 순환 적 으로 사용 합 니 다.
for item in my_list:
if item.flavor == 'banana':
break
else:
raise ValueError('No banana flavor found!')
처음에는 try/except 블록 에서 else 자 구 를 사용 할 필요 가 없다 고 생각 했 을 수도 있 습 니 다.결국 다음 코드 세 션 에서dangerous_call()
이상 을 던 지지 않 고after_call()
만 실 행 될 수 있 습 니 다.그 렇 죠?
try:
dangerous_call()
after_call()
except OSError:
log('OSError...')
그러나after_call()
try 블록 에 넣 어 서 는 안 됩 니 다.뚜렷 하고 정확 하기 위해 서 는 try 블록 에서 예상 치 못 한 문구 만 던 져 야 합 니 다.그래서 아래 처럼 쓰 는 것 이 좋다.
try:
dangerous_call()
except OSError:
log('OSError...')
else:
after_call()
트 리 블록 수 비 는dangerous_call()
발생 할 수 있 는 오류 가 아니 라after_call()
임 이 분명 하 다.그리고 try 블록 이 이상 을 던 지지 않 아야 실행 할 수 있 음 이 분명 하 다after_call()
.컨 텍스트 관리자 와 with 블록
컨 텍스트 관리자 대상 이 존재 하 는 목적 은 with 문 구 를 관리 하 는 것 입 니 다.마치 교체 기의 존재 가 for 문 구 를 관리 하기 위 한 것 과 같 습 니 다.
with 문장의 목적 은 try/finally 모델 을 간소화 하 는 것 이다.이 모드 는 코드 가 실 행 된 후에 특정한 작업 을 수행 하도록 하 는 데 사 용 됩 니 다.그 코드 가 이상,return 구문 또는
sys.exit()
호출 로 중단 되 더 라 도 지정 한 작업 을 수행 합 니 다.finally 자구 의 코드 는 보통 중요 한 자원 을 방출 하거나 임시 변 경 된 상 태 를 복원 하 는 데 사 용 됩 니 다.컨 텍스트 관리자 프로 토 콜 포함enter__ 와exit__ 두 가지 방법.with 문장 이 실 행 될 때,상하 문 관리자 대상 에서 를 호출 합 니 다enter__ 방법with 구문 실행 이 끝나 면 컨 텍스트 관리자 대상 에서 호출 합 니 다.exit__ 방법 은 이것으로 finally 자구 의 역할 을 한다.
🌰 파일 대상 을 컨 텍스트 관리자 로 사용 하 는 것 을 보 여 줍 니 다.
>>> with open('mirror.py') as fp: # fp , __enter__ self
... src = fp.read(60) # fp
...
>>> len(src)
>>> fp # fp
<_io.TextIOWrapper name='mirror.py' mode='r' encoding='UTF-8'>
>>> fp.closed, fp.encoding # fp
(True, 'UTF-8')
>>> fp.read(60) # fp I/O , with , TextIOWrappper.__exit__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: I/O operation on closed file.
Looking Glass 컨 텍스트 관리자 클래스 테스트
>>> from mirror import LookingGlass
>>> with LookingGlass() as what: # LookingGlass ;Python __enter__ , what
... print('Alice, Kitty and Snowdrop') # , what
... print(what)
...
pordwonS dna yttiK ,ecilA #
YKCOWREBBAJ
>>> what # ,with , ,__enter__ , what 'JABBERWOCKY'
'JABBERWOCKY'
>>> print('Back to normal.') #
Back to normal.
mirror.py:Looking Glass 컨 텍스트 관리자 류 의 코드
class LookingGlass:
def __enter__(self): # self ,Python __enter__
import sys
self.original_write = sys.stdout.write # sys.stdout.write ,
sys.stdout.write = self.reverse_write # sys.stdout.write ,
return 'JABBERWOCKY' # 'JABBERWOCKY' , what
def reverse_write(self, text): # sys.stdout.write , text ,
return self.original_write(text[::-1])
def __exit__(self, exc_type, exc_val, traceback): # ,Python __exit__ None, ,
import sys
sys.stdout.write = self.original_write # sys.studout.write
if exc_type is ZeroDivisionError: # , ZeroDivisionError ,
print('Please DO NOT divide by zero!')
return True # True, ,
해석 기 호출enter__ 방법 은 암시 적 인 self 를 제외 하고 어떠한 인자 도 들 어 오지 않 습 니 다.전달exit__ 방법의 세 가지 매개 변 수 는 다음 과 같다.exc_type
이상 클래스(예:ZeroDivisionError)
exc_value
예외 실례.때때로 매개 변수 가 이상 구조 방법 에 전 달 될 수 있 습 니 다.예 를 들 어 오류 메시지 등 매개 변 수 는 exc 를 사용 할 수 있 습 니 다.value.args 가 져 오기
traceback
traceback 대상
with 블록 외 에 Looking Glass 클래스 를 사용 합 니 다.
>>> from mirror import LookingGlass
>>> manager = LookingGlass() # manager , with LookingGlass() as manager
>>> manager
<mirror.LookingGlass object at 0x2a578ac>
>>> monster = manager.__enter__() # __enter__() , monster
>>> monster == 'JABBERWOCKY' # monster 'JABBERWOCKY', True ,
eurT
>>> monster
'YKCOWREBBAJ'
>>> manager
>ca875a2x0 ta tcejbo ssalGgnikooL.rorrim<
>>> manager.__exit__(None, None, None) # manager.__exit__, stdout.write
>>> monster
'JABBERWOCKY'
contextlib 모듈 의 유 틸 리 티 도구closing
대상 이
close()
방법 을 제 공 했 지만 실현 되 지 않 았 다 면enter__/__exit__ 프로 토 콜,그러면 이 함 수 를 사용 하여 상하 문 관리 자 를 구축 할 수 있 습 니 다.suppress
지정 한 이상 을 임시로 무시 하 는 컨 텍스트 관리 자 를 만 듭 니 다.
@contextmanager
이 장식 기 는 간단 한 생 성기 함 수 를 컨 텍스트 관리자 로 바 꾸 어 관리자 프로 토 콜 을 만 들 지 않 아 도 됩 니 다.
ContextDecorator
클래스 기반 컨 텍스트 관리 자 를 정의 하 는 기본 클래스 입 니 다.이 컨 텍스트 관리 자 는 장식 함수 에 도 사용 되 며 관 리 된 컨 텍스트 에서 전체 함 수 를 실행 할 수 있 습 니 다.
ExitStack
이 컨 텍스트 관리 자 는 여러 컨 텍스트 관리자 에 들 어 갈 수 있 습 니 다.with 블록 이 끝 났 을 때 ExitStack 은 스 택 의 각 컨 텍스트 관리자 의 를 후진 선 출 순서에 따라 호출 합 니 다.exit__ 방법with 블록 이 몇 개의 컨 텍스트 관리자 에 들 어 가 는 지 미리 몰 랐 다 면 이 종 류 를 사용 할 수 있 습 니 다.예 를 들 어 임의의 파일 목록 에 있 는 모든 파일 을 동시에 엽 니 다.
@contextmanager 사용 하기
@contextmanager 장식 기 는 컨 텍스트 관리 자 를 만 드 는 모델 코드 의 양 을 줄 일 수 있 습 니 다.완전한 클래스 를 만 들 지 않 아 도 되 기 때문에 을 정의 합 니 다.enter__ 와exit__ 방법,하나의 yield 문 구 를 가 진 생 성 기 를 실현 하여enter__ 방법 반환 값.
@contextmanager 장식 을 사용 하 는 생 성기 에서 yield 문 구 는 함수 의 정의 체 를 두 부분 으로 나 누 는 역할 을 합 니 다.yield 문 앞 에 있 는 모든 코드 가 with 블록 에서 시 작 될 때(즉 해석 기 호출enter__ 방법 시)실행,yield 문장 뒤의 코드 는 with 블록 이 끝 날 때(즉 호출exit__ 방법 시)집행.
mirror_gen.py:생 성 기 를 사용 한 컨 텍스트 관리자
import contextlib
@contextlib.contextmanager # contextmanager
def looking_glass():
import sys
original_write = sys.stdout.write # sys.stdout.write
def reverse_write(text): # reverse_write ; original_write
original_write(text[::-1])
sys.stdout.write = reverse_write # sys.stdout.write reverse_write
yield 'JABBERWOCKY' # , with as
sys.stdout.write = original_write # with , yield ; sys. stdout.write
with looking_glass() as what: # with
print('Alice, Kitty and Snowdrop')
print(what)
print(what)
상기 코드 가 실 행 된 결 과 는 다음 과 같 습 니 다.
pordwonS dna yttiK ,ecilA
YKCOWREBBAJ
JABBERWOCKY
사실 contextlib.contextmanager 장식 기 는 함 수 를 실현 로 포장 합 니 다.enter__ 와exit__ 방법의 종류이런 종류의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 문 구 를 계속 실행 합 니 다.주의:
위의🌰 심각 한 오류 가 있 습 니 다.with 블록 에 이상 을 던 지면 Python 해석 기 가 잡 아서 lookingglass 함수 의 yield 표현 식 에서 다시 던 집 니 다.하지만 잘못된 코드 가 처리 되 지 않 았 기 때문에 lookingglass 함수 가 중단 되 어 원래 의
sys.stdout.write
방법 으로 영원히 회복 되 지 못 해 시스템 이 무효 상태 에 있 습 니 다.mirror_gen_exc.py:생 성 기 를 기반 으로 한 컨 텍스트 관리자 이 며 이상 처 리 를 실현 합 니 다.
import contextlib
@contextlib.contextmanager
def looking_glass():
import sys
original_write = sys.stdout.write
def reverse_write(text):
original_write(text[::-1])
sys.stdout.write = reverse_write
msg = '' # , ;
try:
yield 'JABBERWOCKY'
except ZeroDivisionError: # ZeroDivisionError ,
msg = 'Please DO NOT divide by zero!'
finally:
sys.stdout.write = original_write # sys.stdout.write
if msg:
print(msg) # ,
주의:@contextmanager 장식 기 를 사용 할 때 yield 문 구 를 try/finally 구문 에 넣 거나 with 구문 에 넣 는 것 은 피 할 수 없습니다.컨 텍스트 관리자 의 사용자 가 with 블록 에서 무엇 을 할 지 영원히 모 르 기 때 문 입 니 다.
총결산
이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
로마 숫자를 정수로 또는 그 반대로 변환그 중 하나는 로마 숫자를 정수로 변환하는 함수를 만드는 것이었고 두 번째는 그 반대를 수행하는 함수를 만드는 것이었습니다. 문자만 포함합니다'I', 'V', 'X', 'L', 'C', 'D', 'M' ; 문자열이 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.