프로그래밍 언어/Python

파이썬 "with"문을 활용하는 방법

Rateye 2021. 11. 17. 10:36
728x90
반응형
질문 : 파이썬 "with"문은 무엇을 위해 설계 되었습니까?

나는 with 성명서를 접했다. 저는 파이썬을 몇 달 동안 가볍게 사용해 왔지만 그 존재조차 몰랐습니다! 다소 모호한 상태를 감안할 때 다음과 같이 물어볼 가치가 있다고 생각했습니다.

  1. Python "with" 문은 무엇에 사용되도록 설계되었는가?
  2. 어디에 쓰는 것인가?
  3. 제가 알아야 할 gotchas나 그 사용과 관련된 일반적인 안티패턴이 있나요? 더 나은 경우는 "try..finally" 가 아니라 'with'?
  4. 왜 더 널리 사용되지 않는 건가요?
  5. 어떤 표준 라이브러리가 호환되나요?
답변

  1. 이 문제는 이전에 다른 사용자가 이미 답변했다고 생각하므로 완전성을 위해서만 추가합니다. with 문은 소위 컨텍스트 관리자 에서 일반적인 준비 및 정리 작업을 캡슐화하여 예외 처리를 단순화합니다. 자세한 내용은 PEP 343 에서 확인할 수 있습니다. 예를 들어, open 문은 그 자체로 컨텍스트 관리자입니다. 파일을 열고, 파일 with 문의 컨텍스트에있는 한 실행을 유지하고, 종료하자마자 닫을 수 있습니다. 예외로 인해 또는 일반 제어 흐름 중에 떠났는 지에 관계없이 컨텍스트. 따라서 with 문은 C ++의 RAII 패턴 과 유사한 방식으로 사용할 수 있습니다. 일부 리소스는 with with 컨텍스트를 벗어날 때 해제됩니다.
  2. 몇 가지 예는 다음과 같습니다. with open(filename) as fp: 사용하여 파일 열기, with lock: 사용하여 잠금 획득 (여기서 lock threading.Lock 의 인스턴스입니다). contextlib contextmanager 데코레이터를 사용하여 고유 한 컨텍스트 관리자를 구성 할 수도 있습니다. 예를 들어, 현재 디렉토리를 일시적으로 변경 한 다음 원래 위치로 돌아 가야 할 때 자주 사용합니다.
    from contextlib import contextmanager
    import os
    
    @contextmanager
    def working_directory(path):
        current_dir = os.getcwd()
        os.chdir(path)
        try:
            yield
        finally:
            os.chdir(current_dir)
    
    with working_directory("data/stuff"):
        # do something within data/stuff
    # here I am back again in the original working directory
    sys.stdin , sys.stdoutsys.stderr 을 다른 파일 핸들로 일시적으로 리디렉션하고 나중에 복원하는 또 다른 예입니다.
    from contextlib import contextmanager
    import sys
    
    @contextmanager
    def redirected(**kwds):
        stream_names = ["stdin", "stdout", "stderr"]
        old_streams = {}
        try:
            for sname in stream_names:
                stream = kwds.get(sname, None)
                if stream is not None and stream != getattr(sys, sname):
                    old_streams[sname] = getattr(sys, sname)
                    setattr(sys, sname, stream)
            yield
        finally:
            for sname, stream in old_streams.iteritems():
                setattr(sys, sname, stream)
    
    with redirected(stdout=open("/tmp/log.txt", "w")):
         # these print statements will go to /tmp/log.txt
         print "Test entry 1"
         print "Test entry 2"
    # back to the normal stdout
    print "Back to normal stdout again"
    마지막으로, 임시 폴더를 만들고 컨텍스트를 떠날 때 정리하는 또 다른 예입니다.
    from tempfile import mkdtemp
    from shutil import rmtree
    
    @contextmanager
    def temporary_dir(*args, **kwds):
        name = mkdtemp(*args, **kwds)
        try:
            yield name
        finally:
            shutil.rmtree(name)
    
    with temporary_dir() as dirname:
        # do whatever you want

 

출처 : https://stackoverflow.com/questions/3012488/what-is-the-python-with-statement-designed-for
728x90
반응형