ビット単位の補数の単項演算 Python via this question )を発見し、実際のアプリケーションを考え出そうとしています。そうでない場合は、他の用途で(__invert__
メソッドをオーバーライドして)演算子をオーバーロードしても安全かどうかを判断します。質問の例はTypeError
で失敗し、 リンク 提供されたものはかなり威圧的なようです。使用中の~
を確認するためにいじくり回します:
from bitstring import BitArray
x = 7
print(~x)
# -8
print(BitArray(int=x, length=4).bin)
# '0111'
print(BitArray(int=~x, length=4).bin)
# '1000'
print(~~True, ~~False)
# 1 0
for i in range(-100, 100):
assert i + ~i == -1
assert i ^ ~i == -1
assert bool(i) == ~~bool(i)
私が知っておくべきこの演算子の有効なユースケースのanyの例はありますか?そして、存在する場合でも、int
以外の型に対してこの演算子をオーバーライドすることは、一般的に許容されますか?
ビットごとのNOT演算子の標準的な使用例は、ビットごとの演算です。ビットごとのAND &
、ビットごとのOR |
、ビットごとのXOR ^
、およびビット単位のシフト<<
および>>
。これらは高レベルのアプリケーションではめったに使用されませんが、ビット単位の操作を行う必要がある場合もあるので、なぜそこにあるのか。
もちろん、カスタムタイプの場合はこれらを上書きすることができ、一般的には、そうするときに特定のセマンティクスに従う必要はありません。自分のタイプにとって意味のあるものと、なんらかの方法で演算子にまだ適合するものを選択してください。
操作が曖昧で、Wordや2で説明した方がよい場合は、代わりに標準の方法を使用する必要があります。ただし、特に数値関連の型を使用する場合、ビットごとの演算子に適合する数学的な演算が発生する場合があるため、それらを使用しても問題ありません。
+
や-
などの標準的な演算子を意味のある演算でのみ上書きするのと同じように、ビットごとの演算子についても同じことを行う必要があります。
~~True, ~~False
が(1, 0)
を与える理由は、bool
タイプが独自の__invert__
オペレーションを定義していないためです。ただし、int
にはあります。 bool
は実際にはint
のサブタイプです。したがって、bool
は実際にはすべてのビット単位および算術演算子のロジックを継承します。だからTrue + True == 2
など.
私が知っておくべきこの演算子の有効なユースケースの例はありますか?そして、もしあるとしても、int以外の型のためにこの演算子をオーバーライドすることは一般的に受け入れられますか?
通常、~
演算子は楽しいからといって過負荷にしたくないでしょう。読みにくくなります。ただし、このようなint
以外の型のオーバーロードが意味をなす場合もあります。 SQLAlchemyがSQLAlchemyを活用する方法を見てください。
その演算子を否定演算子(-
)と組み合わせて使用して、数値を1ずつインクリメントできます。次に例を示します。
x = 5
assert -~x == 6
これは、~
演算子を使用した唯一の実用的な方法です。数値以外の場合に使用される他の方法は、一般にコンテキストに依存し、コードを理解するのにある程度の複雑さを追加することがよくあります。 C++、Swift、Rubyなどの言語では、この演算子をオーバーロードして、コードをすばやく消化するのを困難にすることを意味します。
これは、~x
ではなく-x-1
または~my_bool
ではなくnot my_bool
を使用するなど、いくつかのショートカットとして code golf で一般的に使用されます。
他の人が述べたように、リストをトラバースするときにそれは本当にきちんとすることができます。
for i in range(n):
mylist[~i]
#much prettier than mylist[-i-1]
マトリックスを時計回りに90度回転する例を見てみましょう。
def rotate( A):
n = len(A)
for i in range(n/2):
for j in range(n-n/2):
A[i][j], A[~j][i], A[~i][~j], A[j][~i] = \\
A[~j][i], A[~i][~j], A[j][~i], A[i][j]
(このスニペットは here から取得されました)