0

これは機能を悪用していると思いますが、それができるかどうかはまだ気になります。次のようなことをしたいと思います。

with conditional(a):
    print 1

print 1a==Trueの場合にのみパーツが実行されるようにします。これは可能ですか?

編集:人々が以下に述べるように、これは恐ろしいスタイルです。それはただのなぞなぞ\質問です。心臓の弱い人などのためではなく、家でこれを試さないでください。

4

5 に答える 5

9

if条件文はステートメントを使用してすでに提供されているため、これを行う本当の理由はありません。

if a == True:
    print 1

しかし、あなたがただ楽しみを求めているのなら、答えはあなたが本当にできないということです。withコンテンツの実行を停止するconditionalには、そのメソッドで何らかの方法で実行を停止する必要があり__enter__ます。ただし、それを実行できる唯一の方法は、例外を発生させることです。つまり、ケースを処理するためwithtryステートメントでラップしない限り、他のコードは実行されません。a != True

編集:私がOPの条件を使用するためのコメントと投票で起訴されたのを見て(a == True)私はそれをに変更することを検討しましたif a。これはもちろん条件をテストするためのPythonのイディオムです。しかし、OPが何を考えていたのか、そして彼が本当にブール値になりたいのかどうか、そしてブロックを実行したくないのかどうかはわかりませんaa = [1]if a

于 2009-11-27T13:22:39.723 に答える
4
if a is True:
    print 1

withステートメントは、信頼できる出入りコンテキストを提供することを目的としています。

于 2009-11-27T13:09:17.797 に答える
2

私が見る唯一の方法はconditional、引数がfalseの場合に例外を発生させることです。with本文は実行されませんが、それに続くコードも実行されません。もちろん、or句までは実行されませexceptfinally

于 2009-11-27T13:17:53.787 に答える
0

__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ブロックの内側に配置することです。しかし、これを行うことはお勧めしません。

于 2009-11-27T13:52:31.360 に答える
0

個人的には、条件付き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
于 2021-12-07T11:08:09.773 に答える