15

次のようなものを要求したときに実行される特定のコードは何ですか

>>> 1 <= 3 >= 2
True

両方の優先順位が等しく、それが評価の順序である場合、なぜ 2 番目の不等式(3 >= 2)(True >= 2)

たとえば、これらの違いを考えてみましょう

>>> (1 < 3) < 2
True

>>> 1 < 3 < 2
False

2 番目のステートメントを 2 つのステートメントのとして展開するために、Python にハードコードされた単なる構文上のショートカットandですか?

クラスa <= b <= cが別のものに拡張されるように、この動作を変更できますか? 次のような場合のようです

a (logical operator) b (logical operator) c 
    --> (a logical operator b) and (b logical operator c)

しかし、本当の問題は、これがコードにどのように実装されるかです。

私は自分のクラスのいくつかでこの種の動作を複製できるように興味が__lt__ありますが、中間の引数を一定に保持してこれを達成する方法について混乱しています。__gt__

具体例を次に示します。

>>> import numpy as np

>>> tst = np.asarray([1,2,3,4,5,6])

>>> 3 <= tst
array([False, False,  True,  True,  True,  True], dtype=bool)

>>> 3 <= tst <= 5
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
/home/ely/<ipython-input-135-ac909818f2b1> in <module>()
----> 1 3 <= tst <= 5

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

次のように、これをオーバーライドして、配列でも「正常に機能する」ようにするとよいでしょう。

>>> np.logical_and(3 <= tst, tst <= 5)
array([False, False,  True,  True,  True,  False], dtype=bool)

明確化のために追加

コメントでは、私が質問を説明するのに不十分な仕事をしたことが示されています。ここにいくつかの明確な発言があります:

1) 私は、インタプリタが連鎖した 2 つの不等式の間に飛び込むという事実の単純な説明を探しているわけではありません。and私はすでにそれを知っていて、上でそう言いました。

2)私がやりたいこととの類似性については、withステートメント(リンク)を検討してください。以下:

with MyClass(some_obj) as foo:
    do_stuff()

に解凍します

foo = MyClass(some_obj)
foo.__enter__()
try:
    do_stuff()
finally:
    foo.__exit__()

したがって、適切に書くことで、ステートメントMyClass内で多くの特別なことを行うことができます。with

私は、連鎖した不等式の同様のコードアンパッキングがあるかどうかを尋ねています.

これは私の質問、特に例から非常に明確だと思いますが、これでより明確になることを願っています。

4

3 に答える 3

12

あなたが何を探しているのか完全にはわかりませんが、簡単な逆アセンブルはa < b < c、同じバイトコードにコンパイルされていないことを示していますa < b and b < c

>>> import dis
>>>
>>> def f(a, b, c):
...     return a < b < c
...
>>> dis.dis(f)
  2           0 LOAD_FAST                0 (a)
              3 LOAD_FAST                1 (b)
              6 DUP_TOP
              7 ROT_THREE
              8 COMPARE_OP               0 (<)
             11 JUMP_IF_FALSE_OR_POP    21
             14 LOAD_FAST                2 (c)
             17 COMPARE_OP               0 (<)
             20 RETURN_VALUE
        >>   21 ROT_TWO
             22 POP_TOP
             23 RETURN_VALUE
>>>
>>> def f(a, b, c):
...     return a < b and b < c
...
>>> dis.dis(f)
  2           0 LOAD_FAST                0 (a)
              3 LOAD_FAST                1 (b)
              6 COMPARE_OP               0 (<)
              9 JUMP_IF_FALSE_OR_POP    21
             12 LOAD_FAST                1 (b)
             15 LOAD_FAST                2 (c)
             18 COMPARE_OP               0 (<)
        >>   21 RETURN_VALUE

編集 1:さらに掘り下げると、これは numpy の何かがおかしいか間違っていると思います。このコード例を検討してください。期待どおりに機能すると思います。

class Object(object):
    def __init__(self, values):
        self.values = values
    def __lt__(self, other):
        return [x < other for x in self.values]
    def __gt__(self, other):
        return [x > other for x in self.values]

x = Object([1, 2, 3])
print x < 5 # [True, True, True]
print x > 5 # [False, False, False]
print 0 < x < 5 # [True, True, True]

編集2:実際、これは「適切に」機能しません...

print 1 < x # [False, True, True]
print x < 3 # [True, True, False]
print 1 < x < 3 # [True, True, False]

の2番目の比較でブール値を数値と比較していると思います1 < x < 3

編集 3: gt、lt、gte、lte の特別なメソッドからブール値以外の値を返すという考えは好きではありませんが、Python のドキュメントによると、実際には制限されていません。

http://docs.python.org/reference/datamodel.html#object. それ

慣例により、比較が成功すると False と True が返されます。ただし、これらのメソッドは任意の値を返すことができます...

于 2012-10-01T14:23:25.910 に答える
6

どちらも優先順位は同じですが、ドキュメントに従って左から右に評価されます。フォームの式はa <= b <= cに展開されa <= b and b <= cます。

于 2012-09-30T02:45:42.183 に答える
1

しかし、本当の問題は、これがコードにどのように実装されるかです。

インタプリタがそれをどのように変換するか、または何を意味しますか? あなたはすでに言った

a (logical operator) b (logical operator) c 
    --> (a logical operator b) and (b logical operator c)

だから私はあなたがここで何を求めているa < b < cのかわから ない(a < b) and (b < c).


私は自分のクラスのいくつかでこの種の動作を複製できるように興味が__lt__ありますが、中間の引数を一定に保持してこれを達成する方法について混乱しています。__gt__

abとのどちらが独自のクラスのインスタンスであるかによって異なります。and メソッドと and メソッドを実装すると、ある程度はうまくいきますが、ドキュメントでは次のように指摘されています。ca < b < c__lt____gt__

これらのメソッドの引数を交換したバージョンはありません (左の引数が操作をサポートしていないが、右の引数が操作をサポートしている場合に使用されます)。

だから、あなたが望むならInt < MyClass < Int、あなたは運が悪い. 少なくとも必要ですMyClass < MyClass < Something(そのため、クラスのインスタンスは、展開された式の各比較の LHS にあります)。

于 2012-10-01T12:08:05.550 に答える