操作1 <3 <2を返すものは何ですか?

答え:偽



この式が2つの個別の操作で構成されていると仮定した場合、左から右へ: 1 < 3 = True, True( 1) < 2



True



返す1 < 3 = True, True( 1) < 2



が、何らかの理由でFalse



ます。



秘Theは、 1 < 3 < 2



は2つの別個の操作ではなく、1つの複雑な操作であるということです。 式を(Pythonの逆アセンブラーに)逆アセンブルしましょう。 ご覧のとおり、出力は非常に具体的なコードです。



 from dis import dis dis(lambda: 1<3<2) 1 0 LOAD_CONST 1 (1) 3 LOAD_CONST 2 (3) 6 DUP_TOP 7 ROT_THREE 8 COMPARE_OP 0 (<) 11 JUMP_IF_FALSE_OR_POP 21 14 LOAD_CONST 3 (2) 17 COMPARE_OP 0 (<) 20 RETURN_VALUE >> 21 ROT_TWO 22 POP_TOP 23 RETURN_VALUE
      
      







ここで何が起こるか見てみましょう。 スタックに2つの定数をロードし、後で比較するために後者を複製します。 スタックを裏返します。 2つの定数を引き出し、比較します。 結果をスタックに入れます。 落ちる場合は、終了します。 Truの場合、スタックからTruを取得します。 3番目の定数をロードし、前に複製した2番目の定数と比較します。 1 <2 <3 <4 ...を個別に逆アセンブルできます。コードは上記のコードのようになり、対応するブロックのみが繰り返されます。 それでも、1つの複雑な演算子になります。



そして、ここにコード1<3 and 3<2



ます。 それは非常に線形で理解しやすいです:



 dis(lambda: 1<3 and 3<2) 1 0 LOAD_CONST 1 (1) 3 LOAD_CONST 2 (3) 6 COMPARE_OP 0 (<) 9 JUMP_IF_FALSE_OR_POP 21 12 LOAD_CONST 2 (3) 15 LOAD_CONST 3 (2) 18 COMPARE_OP 0 (<) >> 21 RETURN_VALUE
      
      







1<3 and 3<2



を書く方が簡単なため、このような演算子が必要な理由。 たとえば、yamlを解析します。

 age: title: Age items: 1: up to 18 2: 18-25 3: above 25
      
      







次のコード:



 def range_age(age): for k, v in data['age'].items.items(): v = v.replace('up to','{}<') v = v.replace('above','{}>') v = v.replace('-','<={}<=') if eval(v.format(age)): return k
      
      







みなさん、良い一日を!



PS。 他の言語に類似した複雑な演算子はありますか?



All Articles