質問はすでに十分に回答されています(つまり、@ Paul Rooneyの回答)が、これらの回答の正しさを検証することも可能です。
既存の答えを要約しましょう。これ..
は単一の構文要素ではありません!
ソースコードがどのように「トークン化」されているかを確認できます。これらのトークンは、コードの解釈方法を表します。
>>> from tokenize import tokenize
>>> from io import BytesIO
>>> s = "1..__truediv__"
>>> list(tokenize(BytesIO(s.encode('utf-8')).readline))
[...
TokenInfo(type=2 (NUMBER), string='1.', start=(1, 0), end=(1, 2), line='1..__truediv__'),
TokenInfo(type=53 (OP), string='.', start=(1, 2), end=(1, 3), line='1..__truediv__'),
TokenInfo(type=1 (NAME), string='__truediv__', start=(1, 3), end=(1, 14), line='1..__truediv__'),
...]
そのため、文字列1.
は数値として解釈され、2番目.
はOP(演算子、この場合は「属性を取得」演算子)であり、__truediv__
はメソッド名です。したがって、これは__truediv__
float のメソッドにアクセスするだけ1.0
です。
生成されたバイトコードを表示する別の方法は、それをアセンブルすることです。これは実際に、いくつかのコードが実行されたときに実行される命令を示しています。 dis
>>> import dis
>>> def f():
... return 1..__truediv__
>>> dis.dis(f)
4 0 LOAD_CONST 1 (1.0)
3 LOAD_ATTR 0 (__truediv__)
6 RETURN_VALUE
基本的に同じことを言っています。__truediv__
定数の属性をロードします1.0
。
ご質問について
そして、(可能であれば)より複雑なステートメントでそれをどのように使用できますか?
コードが何をしているかがはっきりしないからといって、そのようなコードを書くことは決してできません。したがって、より複雑なステートメントでは使用しないでください。「単純な」ステートメントでは使用しないでください。少なくとも、命令を区切るために括弧を使用する必要があります。
f = (1.).__truediv__
これは明らかに読みやすくなりますが、次のようなものになります。
from functools import partial
from operator import truediv
f = partial(truediv, 1.0)
さらに良いでしょう!
を使用したアプローチでは、Pythonのデータモデルpartial
も維持されます(1..__truediv__
アプローチはそうではありません)。これは、次の小さなスニペットで示すことができます。
>>> f1 = 1..__truediv__
>>> f2 = partial(truediv, 1.)
>>> f2(1+2j) # reciprocal of complex number - works
(0.2-0.4j)
>>> f2('a') # reciprocal of string should raise an exception
TypeError: unsupported operand type(s) for /: 'float' and 'str'
>>> f1(1+2j) # reciprocal of complex number - works but gives an unexpected result
NotImplemented
>>> f1('a') # reciprocal of string should raise an exception but it doesn't
NotImplemented
これはがで1. / (1+2j)
評価されないためです- 通常の操作が戻ったときに逆の操作が呼び出されることを確認しますが、直接操作するときにこれらのフォールバックはありません。この「予想される動作」の喪失が、(通常)マジックメソッドを直接使用するべきではない主な理由です。float.__truediv__
complex.__rtruediv__
operator.truediv
NotImplemented
__truediv__
(1).__truediv__
ため1..__truediv__
、は実際にはと同じではありません。また、あなたはまた、使用することができます`(スペースで)int.__truediv__
float.__truediv__
1 .__truediv__