python 의 키워드"with"와 컨 텍스트 관리 자 를 정확하게 이해 합 니 다.

머리말
만약 에 소스 코드 를 읽 는 습관 이 있다 면 우수한 코드 가'with'키 워드 를 가 진 문 구 를 자주 볼 수 있 습 니 다.이것 은 보통 어떤 장면 에 사 용 됩 니까?오늘 은 with 와 컨 텍스트 관리자 에 대해 이야기 하 겠 습 니 다.
파일,데이터베이스 연결,socket 과 같은 시스템 자원 에 대해 프로그램 이 이 자원 을 열 고 업무 논 리 를 실행 한 후에 해 야 할 일 은 이 자원 을 닫 는 것 입 니 다.
예 를 들 어 Python 프로그램 이 파일 을 열 고 파일 에 내용 을 쓰 고 다 쓴 후에 이 파일 을 닫 아야 합 니 다.그렇지 않 으 면 어떤 상황 이 발생 할 까요?극단 적 인 상황 에서'Too many open files'오류 가 발생 할 수 있 습 니 다.시스템 이 열 수 있 는 최대 파일 수 는 제한 되 어 있 기 때 문 입 니 다.
마찬가지 로 데이터베이스 에 대해 서 는 접속 수가 너무 많아 서 제때에 닫 히 지 않 으 면'Can not connect to MySQL server Too many connections'가 나타 날 수 있 습 니 다.데이터베이스 연결 은 매우 비 싼 자원 이기 때문에 무제 한 생 성 이 불가능 합 니 다.
파일 을 정확하게 닫 는 방법 을 봅 시다.
일반 판:

def m1():
 f = open("output.txt", "w")
 f.write("python  ")
 f.close()
이렇게 쓰 면 잠재 적 인 문제 가 있 습 니 다.write 를 호출 하 는 과정 에서 이상 이 발생 하여 후속 코드 가 계속 실행 되 지 못 하고 close 방법 이 정상적으로 호출 되 지 못 하기 때문에 자원 은 이 프로그램 점용 자 에 의 해 계속 방출 됩 니 다.그렇다면 코드 를 어떻게 개선 해 야 합 니까?
진급 판:

def m2():
 f = open("output.txt", "w")
 try:
 f.write("python  ")
 except IOError:
 print("oops error")
 finally:
 f.close()
개량 버 전의 프로그램 은 이상 이 발생 할 수 있 는 코드 에 대해 try 캡 처 를 하고 try/finally 문 구 를 사용 합 니 다.이 문 구 는 try 코드 블록 에서 프로그램 에 이상 이 생기 면 후속 코드 는 더 이상 실행 되 지 않 고 except 코드 블록 으로 바로 이동 합 니 다.어쨌든 finally 블록의 코드 는 최종 적 으로 실 행 될 것 이다.따라서 close 를 finally 코드 에 넣 으 면 파일 이 닫 힙 니 다.
고급 버 전:

def m3():
 with open("output.txt", "w") as f:
 f.write("Python  ")
더욱 간결 하고 우아 한 방식 은 with 키 워드 를 사용 하 는 것 이다.open 방법의 반환 값 은 변수 f 에 할당 되 며,with 코드 블록 을 떠 날 때 시스템 은 자동 으로f.close() 방법 을 호출 합 니 다.with 의 역할 은 try/finally 문 구 를 사용 하 는 것 과 같 습 니 다.그렇다면 그것 의 실현 원 리 는 무엇 입 니까?
with 의 원 리 를 말 하기 전에 다른 개념 과 관련 되 어야 하 는데 그것 이 바로 문맥 관리자(Context Manager)이다.
컨 텍스트 관리자__enter__() __exit__() 방법 을 실현 한 모든 대상 을 문맥 관리자 라 고 할 수 있 고 문맥 관리자 대상 은 with 키 워드 를 사용 할 수 있 습 니 다.분명히 파일(file)대상 도 상하 문 관리 자 를 실현 했다.
그렇다면 파일 대상 은 어떻게 이 두 가지 방법 을 실현 합 니까?우 리 는 이러한 종류의 실현__enter__() __exit__() 방법 을 모 의 할 수 있다.

class File():

 def __init__(self, filename, mode):
 self.filename = filename
 self.mode = mode

 def __enter__(self):
 print("entering")
 self.f = open(self.filename, self.mode)
 return self.f

 def __exit__(self, *args):
 print("will exit")
 self.f.close()
__enter__()방법 은 자원 대상 을 되 돌려 줍 니 다.여기 가 바로 당신 이 열 려 고 하 는 파일 대상 입 니 다.__exit__() 방법 으로 제거 작업 을 처리 합 니 다.
File 클래스 가 상하 문 관리 자 를 실 현 했 기 때문에,이 제 는 with 문장 을 사용 할 수 있 습 니 다.

with File('out.txt', 'w') as f:
 print("writing")
 f.write('hello, python')
이렇게 하면 close 방법 을 표시 할 필요 가 없습니다.시스템 에서 자동 으로 호출 되 고 중간 에 이상 close 방법 이 발생 하 더 라 도 호출 됩 니 다.
contextlib
Python 은 contextmanager 의 장식 기 를 제공 하여 컨 텍스트 관리자 의 실현 방식 을 더욱 간소화 했다.yield 를 통 해 함 수 를 두 부분 으로 나 누고 yield 이전의 문 구 는__enter__ 방법 에서 실 행 됩 니 다.yield 후의 문 구 는__exit__ 방법 에서 실 행 됩 니 다.yield 뒤에 바짝 붙 어 있 는 값 은 함수 의 반환 값 입 니 다.

from contextlib import contextmanager

@contextmanager
def my_open(path, mode):
 f = open(path, mode)
 yield f
 f.close()
호출

with my_open('out.txt', 'w') as f:
 f.write("hello , the simplest context manager")
총결산
Python 은 with 문법 을 제공 하여 자원 작업 을 간소화 하 는 후속 제거 작업 을 제공 합 니 다.try/finally 의 대체 방법 으로 원 리 를 문맥 관리자 위 에 세 웁 니 다.그 밖 에 Python 은 contextmanager 장식 기 를 제공 하여 상하 관리자 의 실현 방식 을 더욱 간소화 했다.이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.

좋은 웹페이지 즐겨찾기