これは機能を悪用していると思いますが、それができるかどうかはまだ気になります。次のようなことをしたいと思います。
with conditional(a):
print 1
print 1
a==Trueの場合にのみパーツが実行されるようにします。これは可能ですか?
編集:人々が以下に述べるように、これは恐ろしいスタイルです。それはただのなぞなぞ\質問です。心臓の弱い人などのためではなく、家でこれを試さないでください。
これは機能を悪用していると思いますが、それができるかどうかはまだ気になります。次のようなことをしたいと思います。
with conditional(a):
print 1
print 1
a==Trueの場合にのみパーツが実行されるようにします。これは可能ですか?
編集:人々が以下に述べるように、これは恐ろしいスタイルです。それはただのなぞなぞ\質問です。心臓の弱い人などのためではなく、家でこれを試さないでください。
if
条件文はステートメントを使用してすでに提供されているため、これを行う本当の理由はありません。
if a == True:
print 1
しかし、あなたがただ楽しみを求めているのなら、答えはあなたが本当にできないということです。with
コンテンツの実行を停止するconditional
には、そのメソッドで何らかの方法で実行を停止する必要があり__enter__
ます。ただし、それを実行できる唯一の方法は、例外を発生させることです。つまり、ケースを処理するためwith
のtry
ステートメントでラップしない限り、他のコードは実行されません。a != True
編集:私がOPの条件を使用するためのコメントと投票で起訴されたのを見て(a == True
)私はそれをに変更することを検討しましたif a
。これはもちろん条件をテストするためのPythonのイディオムです。しかし、OPが何を考えていたのか、そして彼が本当にブール値になりたいのかどうか、そしてブロックを実行したくないのかどうかはわかりません。a
a = [1]
if a
if a is True:
print 1
with
ステートメントは、信頼できる出入りコンテキストを提供することを目的としています。
私が見る唯一の方法はconditional
、引数がfalseの場合に例外を発生させることです。with
本文は実行されませんが、それに続くコードも実行されません。もちろん、or句までは実行されませexcept
んfinally
。
__enter__関数と__exit__関数を持つクラスAがあるとしましょう。
class A:
def __init__(self, i):
self.b = i
def __exit__(*args, **kwargs):
print "exit"
def __enter__(*args, **kwargs):
print "enter"
そして、オブジェクトcのbが1に等しいかどうかをチェックする関数Bは、それ以外の場合は渡されます。
def b(c):
if c.b == 1:
return c
else:
pass
私は達成することができます:
with b(A(1)):
print 10
enter
10
exit
ただし、 withには何も処理できないため、bが渡されると、AttributeErrorがスローされます。解決策はwith b(A(1)):
、try/exceptブロックの内側に配置することです。しかし、これを行うことはお勧めしません。
個人的には、条件付きwithステートメントのユースケースがあります。私の場合、まだ完了していないジョブを実行し、後で完了のマークを付けたいと思います。ナイーブコード:
if not job_done_file.exists():
commands
on multiple
lines
job_done_file.touch()
これの問題は、最後に簡単に忘れることができることです。また、 2回touch()
書く必要があるのも面倒です。job_done_file
C ++では、これを行うことができます。
template <typename Function>void do_job(Function func, Path & job_done_file) {
if (!job_done_file.exists()) {
func();
job_done_file.touch();
}
}
…
do_job([]() {
commands;
on multiple;
lines;
}, "/path/to/job_done_file");
ただし、Pythonでは、ラムダは1行のみで構成でき、戻り値が必要です。したがって、代わりに、プログラム全体で1回だけ関数を使用する場合でも、関数参照として渡す完全な関数を作成する必要があります。
代わりに私がすることはこれです:
@contextmanager
def do_job(job_done_file):
yield not job_done_file.exists()
job_done_file.touch()
…
with do_job('/path/to/job_done_file') as not_done:
if not_done:
commands
on multiple
lines