if… else 문 다음에 컨텍스트 관리자를 열어 둡니다. [중복]
조건문이 다른 다음 구성표가 있습니다 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)
...
마지막 줄 remote
은 sftp
개체 / 컨텍스트 관리자가 만료 되었기 때문에 실패합니다 .
Python에서 Conditional with statement를 읽었 지만 여기에서는 정확히 동일하지 않습니다. 원격이 아닌 경우에 대해 더미 컨텍스트 관리자를 만들 수 있지만 충분할지는 모르겠습니다.
나는 사용에 대해 생각해 ExitStack
보았지만 더 많은 파일을 열 때 복잡해 보일 까봐 두렵다 . 더 많은 코드가 도착하면 각각의 간단한 파일을 with _open(...) as f:
읽기 어려운 것으로 다시 작성해야 할 것이다 stack.enter_context(_open(...))
.
이 경우 가장 간단한 해결책은 무엇입니까? (가능하면 새로운 기능 생성을 피하고 if ... else 흐름을 단순하게 유지)
답변
코드의 주요 기능은 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 을 사용하지만 아이디어를 얻기 위해)