La question est déjà suffisamment répondu (c'est à dire @Paul Rooneys réponse), mais il est également possible de vérifier l'exactitude de ces réponses.
Permettez-moi de récapituler les questions / réponses: L' ..
n'est pas un seul élément syntaxique!
Vous pouvez vérifier le code source est "sous". Ces jetons représentent la façon dont le code est interprété:
>>> 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__'),
...]
Ainsi, la chaîne 1.
est interprétée comme un numéro, le deuxième .
est une OP (opérateur, dans ce cas, l'attribut" opérateur) et l' __truediv__
est le nom de la méthode. Donc c'est l'accès à l' __truediv__
méthode du flotteur 1.0
.
Une autre façon de visualiser le bytecode généré est-à - dis
assembler . Cette montre, en réalité, les instructions qui sont exécutées lorsque le code est exécuté:
>>> 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
Qui dit essentiellement la même. Il charge l'attribut __truediv__
de la constante 1.0
.
Concernant votre question
Et comment pouvez-vous l'utiliser dans un environnement plus complexe déclaration (si possible)?
Même s'il est possible que vous ne devrait jamais écrire du code comme ça, tout simplement parce qu'il ne sait pas ce que fait le code. Donc merci de ne pas l'utiliser dans plus d'instructions complexes. J'irais même plus loin que vous ne devriez pas l'utiliser dans la "simple", au moins vous devez utiliser des parenthèses pour séparer les instructions:
f = (1.).__truediv__
ce serait vraiment plus lisible - mais quelque chose le long des lignes de:
from functools import partial
from operator import truediv
f = partial(truediv, 1.0)
serait encore mieux!
L'approche à l'aide partial
préserve python du modèle de données ( 1..__truediv__
approche ne fonctionne pas!) ce qui peut être démontrée par ce petit extrait:
>>> 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
C'est parce qu' 1. / (1+2j)
n'est pas évalué en float.__truediv__
mais avec complex.__rtruediv__
- operator.truediv
fait en sorte que l'opération inverse est appelée lorsque le fonctionnement normal des retours NotImplemented
mais vous n'avez pas ces réserves, quand vous travaillez sur __truediv__
directement. Cette perte de "comportement attendu" est la principale raison pour laquelle vous avez (normalement) ne doivent pas utiliser les méthodes magiques directement.