파이썬에서는 진술 포함 코드를 더욱 깔끔하고 읽기 쉽게 만들기 위해 예외 처리에 사용됩니다. 파일 스트림과 같은 공통 리소스의 관리를 단순화합니다. with 문을 사용하여 코드를 더욱 깔끔하게 만드는 방법에 대한 다음 코드 예제를 살펴보세요.
파이썬3
자바 샘플 프로그램
# file handling> # 1) without using with statement> file> => open> (> 'file_path'> ,> 'w'> )> file> .write(> 'hello world !'> )> file> .close()> # 2) without using with statement> file> => open> (> 'file_path'> ,> 'w'> )> try> :> > file> .write(> 'hello world'> )> finally> :> > file> .close()> |
>
>
파이썬3
# using with statement> with> open> (> 'file_path'> ,> 'w'> ) as> file> :> > file> .write(> 'hello world !'> )> |
powershell 여러 줄 주석
>
>
처음 두 구현과 달리 with 문을 사용할 때는 file.close()를 호출할 필요가 없습니다. with 문 자체는 리소스의 적절한 획득 및 해제를 보장합니다. 첫 번째 구현에서 file.write() 호출 중 예외가 발생하면 파일이 제대로 닫히지 않아 코드에 여러 버그가 발생할 수 있습니다. 즉, 파일이 제대로 닫힐 때까지 파일의 많은 변경 사항이 적용되지 않습니다. 위 예제의 두 번째 접근 방식은 모든 예외를 처리하지만 with 문을 사용하면 코드가 간결해지고 훨씬 더 읽기 쉬워집니다. 따라서 with 문은 리소스를 사용하는 코드가 완전히 실행될 때 리소스가 제대로 해제되도록 보장하여 버그와 누수를 방지하는 데 도움이 됩니다. with 문은 위에 표시된 대로 파일 스트림과 잠금, 소켓, 하위 프로세스 및 텔넷 등과 함께 널리 사용됩니다.
사용자 정의 객체에서 with 문 지원
open()에는 with 문과 함께 사용할 수 있게 해주는 특별한 기능이 없으며 사용자 정의 객체에서도 동일한 기능을 제공할 수 있습니다. 개체에서 with 문을 지원하면 어떤 리소스도 열어두지 않게 됩니다. 사용자 정의 객체에서 with 문을 사용하려면 객체 메서드에 __enter__() 및 __exit__() 메서드만 추가하면 됩니다. 추가 설명을 위해 다음 예를 고려하십시오.
파이썬3
# a simple file writer object> class> MessageWriter(> object> ):> > def> __init__(> self> , file_name):> > self> .file_name> => file_name> > > def> __enter__(> self> ):> > self> .> file> => open> (> self> .file_name,> 'w'> )> > return> self> .> file> > def> __exit__(> self> ,> *> args):> > self> .> file> .close()> # using with statement with MessageWriter> with MessageWriter(> 'my_file.txt'> ) as xfile:> > xfile.write(> 'hello world'> )> |
>
>
위의 코드를 살펴보겠습니다. 눈치 채셨다면 with 키워드 뒤에 오는 것은 MessageWriter의 생성자입니다. 실행이 with 문의 컨텍스트에 들어가자마자 MessageWriter 객체가 생성되고 Python은 __enter__() 메서드를 호출합니다. 이 __enter__() 메서드에서 객체에 사용하려는 리소스를 초기화합니다. 이 __enter__() 메서드는 항상 획득한 리소스의 설명자를 반환해야 합니다. 리소스 설명자란 무엇입니까? 요청된 리소스에 액세스하기 위해 운영 체제에서 제공하는 핸들입니다. 다음 코드 블록에서 file은 파일 스트림 리소스의 설명자입니다.
파이썬
자바 메소드
file> => open> (> 'hello.txt'> )> |
>
>
위에 제공된 MessageWriter 예제에서 __enter__() 메서드는 파일 설명자를 생성하고 이를 반환합니다. 여기서 xfile이라는 이름은 __enter__() 메서드에서 반환된 파일 설명자를 참조하는 데 사용됩니다. 획득한 리소스를 사용하는 코드 블록은 with 문의 블록 내부에 배치됩니다. with 블록 내부의 코드가 실행되자마자 __exit__() 메서드가 호출됩니다. 획득한 모든 리소스는 __exit__() 메서드에서 해제됩니다. 이것이 사용자 정의 객체에 with 문을 사용하는 방법입니다. 사용자 정의 객체에서 with 문 지원을 제공하는 __enter__() 및 __exit__() 메서드의 이 인터페이스를 호출합니다. 컨텍스트 관리자 .
contextlib 모듈
위에 표시된 클래스 기반 컨텍스트 관리자는 사용자 정의 객체에서 with 문을 지원하는 유일한 방법은 아닙니다. 그만큼 contextlib 모듈은 기본 컨텍스트 관리자 인터페이스를 기반으로 구축된 몇 가지 추가 추상화를 제공합니다. 다음은 contextlib 모듈을 사용하여 MessageWriter 객체에 대한 컨텍스트 관리자를 다시 작성하는 방법입니다.
모두 대문자 명령 엑셀
파이썬3
from> contextlib> import> contextmanager> class> MessageWriter(> object> ):> > def> __init__(> self> , filename):> > self> .file_name> => filename> > @contextmanager> > def> open_file(> self> ):> > try> :> > file> => open> (> self> .file_name,> 'w'> )> > yield> file> > finally> :> > file> .close()> # usage> message_writer> => MessageWriter(> 'hello.txt'> )> with message_writer.open_file() as my_file:> > my_file.write(> 'hello world'> )> |
>
>
이 코드 예제에서는 생산하다 문 정의에서 open_file() 함수는 다음과 같습니다. 생성기 기능 . 이 open_file() 함수가 호출되면 file이라는 리소스 설명자가 생성됩니다. 그런 다음 이 리소스 설명자는 호출자에게 전달되고 여기서는 my_file 변수로 표시됩니다. with 블록 내부의 코드가 실행된 후 프로그램 제어는 open_file() 함수로 다시 돌아갑니다. open_file() 함수는 실행을 재개하고 Yield 문 다음에 나오는 코드를 실행합니다. Yield 문 뒤에 나타나는 이 코드 부분은 획득한 리소스를 해제합니다. 여기의 @contextmanager는 장식가 . 이전 클래스 기반 구현과 이 생성기 기반 컨텍스트 관리자 구현은 내부적으로 동일합니다. 후자가 더 읽기 쉬워 보이지만 생성자, 데코레이터 및 산출량에 대한 지식이 필요합니다.