if… else 문 다음에 컨텍스트 관리자를 열어 둡니다. [중복]

Nov 23 2020

조건문이 다른 다음 구성표가 있습니다 with.

if not remote:
    _open = open
    os.chdir(localpath)
else:
    sftp = pysftp.Connection(host, username=user, password=sftppwd)
    with sftp:
        sftp.chdir(remotepath)
        _open = sftp.open

with _open('myfile', 'rb') as f:        # and then lots of other files are opened too
    x = f.read(4)
    ...

마지막 줄 remotesftp개체 / 컨텍스트 관리자가 만료 되었기 때문에 실패합니다 .

Python에서 Conditional with statement를 읽었 지만 여기에서는 정확히 동일하지 않습니다. 원격이 아닌 경우에 대해 더미 컨텍스트 관리자를 만들 수 있지만 충분할지는 모르겠습니다.

나는 사용에 대해 생각해 ExitStack보았지만 더 많은 파일을 열 때 복잡해 보일 까봐 두렵다 . 더 많은 코드가 도착하면 각각의 간단한 파일을 with _open(...) as f:읽기 어려운 것으로 다시 작성해야 할 것이다 stack.enter_context(_open(...)).

이 경우 가장 간단한 해결책은 무엇입니까? (가능하면 새로운 기능 생성을 피하고 if ... else 흐름을 단순하게 유지)

답변

2 norok2 Nov 23 2020 at 06:59

코드의 주요 기능은 with _open(): ...컨텍스트 관리자가 원격 분기 의 다른 컨텍스트 관리자 내에 있고 다른 경우에는 자유롭게 로밍 되기를 원한다는 것 입니다. 가장 쉬운 방법은 더미 컨텍스트 관리자를 사용하는 것입니다. 여기에서 더 자세히 설명합니다. Python에서 null (no-op) 컨텍스트 관리자를 어떻게 작성합니까?

간단히 말해, 원격이 아닌 경우에 더미 컨텍스트 관리자를 설정합니다. 예 :

import os
# from contextlib import suppress as nullcontext  # Python 3.4+
from contextlib import nullcontext  # Python 3.7+
import pysftp


remote = False
localpath = '.'
remotepath = '.'

if not remote:
    _open_cm = nullcontext()
    _open_cm.chdir = os.chdir
    _open_cm.open = open
    _path = localpath
else:
    _open_cm = pysftp.Connection(host, username=user, password=sftppwd)
    _path = remotepath

with _open_cm:
    _open_cm.chdir(_path)
    with _open_cm.open('myfile', 'rb') as f:
        x = f.read(4)
        ...

(경고! 위의 코드를 테스트하지 않았으며 monkey-patching 을 사용하지만 아이디어를 얻기 위해)