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)
...
オブジェクト/コンテキストマネージャの有効期限が切れているremote
ため、最後の行は失敗しsftp
ます。
PythonでConditionalwithステートメントを読みましたが、ここではまったく同じではありません。リモート以外の場合にダミーのコンテキストマネージャーを作成できますが、それで十分かどうかはわかりません。
使用することを考えましたExitStack
が、さらにファイルを開くと複雑に見えるのではないかと思います。コードが到着しwith _open(...) as f:
たら、単純なものを読みにくくする必要がありstack.enter_context(_open(...))
ます。
この場合の最も簡単な解決策は何ですか?(可能であれば新しい関数の作成を避け、...それ以外の場合は単純に保ちます)
回答
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)
...
(警告!私は上記のコードをテストしていません、そしてそれはモンキーパッチを使用しますが、あなたにアイデアを得るためだけです)