この式が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。 他の言語に類似した複雑な演算子はありますか?