该问题已经得到足够的答案(即@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.
被解释为数字,第二个.
是OP(运算符,在这种情况下为“ get attribute”运算符),而则__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)
会更好!
使用的方法partial
还保留了python的数据模型(该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__
(带有空格)`