Le module operator
contient des fonctions qui font ce que font les opérateurs. Exemple :
>>> from operator import add, gt >>> add(1, 1) # fait en fonction ce que ferait 1 + 1 >>> gt(1, 2) # fait en fonction ce que ferait 1 > 2 |
On a donc dans le module operator
de quoi remplacer les opérateurs +
, <
, not
, etc. par des fonctions.
Les opérateurs or
et and
n'ont pas de fonctions équivalentes car ils short circuitent, ce que ne peut pas faire une fonction. operator.and_
et operator.or_
sont des fonctions pour &
et |
, par pour or
et and
.
Il y a des opérateurs qu'on oublie souvent, comme l'opérateur []
. Le module operator
contient des fonctions pour lui également.
>>> from operator import getitem, getslice >>> lst = [1, 2, 3] >>> lst[0] 1 >>> getitem(lst, 0) 1 >>> lst[:2] [1, 2] >>> getslice(lst, 0, 2) [1, 2] |
On oublie parfois l'opérateur ".". Il y a une fonction builtin pour ça:
>>> class Classe(object): ... def __init__(self, type): ... self.type = type ... >>> c = Classe('cm2') >>> c.type 'cm2' >>> getattr(c, 'type') 'cm2' |
Mais le plus étonnant dans le module operator
, c'est qu'il a des fonctions qui retournent... des fonctions.
>>> from operator import itemgetter >>> getfirst = itemgetter(0) >>> getfirst([1, 2, 3]) 1 >>> getfirst('abc') 'a' >>> getsecond = itemgetter(1) >>> getsecond([1, 2, 3]) 2 >>> getsecond("abc") 'b' >>> getlast = itemgetter(-1) >>> getlast(range(100)) 99 |
Ici on créer des fonctions qui ont pour seul triste but dans la vie de retourner l'élément à l'index donné. getfirst
retournera l'élément 0
. getsecond
retournera l'élément à l'index 1
. getlast
retournera l'élément à l'index -1
. itemgetter(
) est un créateur de fonction qui ne font que ça: retourner un seul élément.
On pourrait aussi le faire avec une lambda:
>>> getfirst = lambda x: x[0] >>> getfirst([1, 2, 3]) 1 |
On a le même chose de chose pour les attributs. attrgetter
est une fonction qui crée une fonction. La fonction créée retourne toujour la valeur du même attribut.
>>> from operator import attrgetter >>> gettype = attrgetter('type') # crée une fonction qui ... >>> gettype(Classe('cm2')) # ... retourne la valeur de l'attribut 'type' 'cm2' >>> gettype(Classe('6eme')) '6eme' |
On pourrait aussi le faire avec une lambda
:
>>> gettype = lambda x: x.type >>> gettype(Classe('6eme')) '6eme' |
Ces fonctions n'ont pas l'air utile comme ça, mais en Python les fonctions peuvent être passées en paramètres. Cela permet donc de faire des choses intéressante comme de l'injection de dépendance. C'est notamment ainsi que fonctionne key
dans sorted().
Bref, jetez un coup d'oeil à operator, il est plein comme un oeuf:
>>> from operator import <tab> abs delitem getslice ilshift ior isSequenceType le neg sequenceIncludes add delslice gt imod ipow is_ lshift not_ setitem and_ div iadd imul irepeat is_not lt or_ setslice attrgetter eq iand index irshift isub methodcaller pos sub concat floordiv iconcat indexOf isCallable itemgetter mod pow truediv contains ge idiv inv isMappingType itruediv mul repeat truth countOf getitem ifloordiv invert isNumberType ixor ne rshift xor |
On pourrait le faire avec un lambda mais dans CPython, ce serait plus lent
Ca veut dire quoi l’opérator and “short-circuit” ?
Merki !
l’opérator and short-circuit signifie que si tu fais
c = f(a) and f(b)
f(b) n’est pas évalué si f(a) est faux
Xavier> Merci pour l’explication !
Ah ouais :o
Je connaissais pas ! Cool merci :D
Ça va m’être pratique ça ^^
C’est la caverne l’Ali Baba ici!
J’ai récemment trouvé quelque chose du même goût (je trouve).
Ça fait partie du module functools (qui a plusieurs truc chouettes dont les lru_wrapper à partir de 3.2, etc), il s’agit de functools.partial.
Si vous avez une fonction qui prend plusieurs paramètres mais que vous voulez faire en sorte qu’un des paramètre aient une (autre) valeur par défaut, vous pouvez faire.
base2 = functools.partial(int, base=2)
base2(10)
http://docs.python.org/3/library/functools.html
Pour répondre à Zariko.
Je préfère le terme “évaluation paresseuse” à “short-circuite”.
Les deux notions ne sont pas égales. Un short-circuit et une évaluation paresseuse avec un retour le plus tôt possible, alors qu’on peut appliquer l’évaluation paresseuses à des choses très différences comme les générateurs. C’est une notion plus large que le short-circuit.