10.3. operator — Opérateurs standards en tant que fonctions

Code source : Lib/operator.py


The operator module exports a set of efficient functions corresponding to the intrinsic operators of Python. For example, operator.add(x, y) is equivalent to the expression x+y. The function names are those used for special class methods; variants without leading and trailing __ are also provided for convenience.

Les fonctions sont divisées en différentes catégories selon l’opération effectuée : comparaison entre objets, opérations logiques, opérations mathématiques ou opérations sur séquences.

Les fonctions de comparaison s’appliquent à tous les objets, et leur nom vient des opérateurs de comparaison qu’elles implémentent :

operator.lt(a, b)
operator.le(a, b)
operator.eq(a, b)
operator.ne(a, b)
operator.ge(a, b)
operator.gt(a, b)
operator.__lt__(a, b)
operator.__le__(a, b)
operator.__eq__(a, b)
operator.__ne__(a, b)
operator.__ge__(a, b)
operator.__gt__(a, b)

Effectue une « comparaison riche » entre a et b. Plus précisément, lt(a, b) équivaut à a < b, le(a, b) équivaut à a <= b, eq(a, b) équivaut à a == b, ne(a, b) équivaut à a != b, gt(a, b) équivaut à a > b et ge(a, b) équivaut à a >= b. Notez que ces fonctions peuvent renvoyer n’importe quelle valeur, convertible ou non en booléen. Voir Comparaisons pour plus d’informations sur les méthodes de comparaison riches.

En général, les opérations logiques s’appliquent aussi à tous les objets et implémentent les tests de vérité, d’identité et les opérations booléennes :

operator.not_(obj)
operator.__not__(obj)

Renvoie le résultat de not obj. (Notez qu’il n’existe pas de méthode __not__() pour les instances d’objet; seul le cœur de l’interpréteur définit cette opération. Le résultat dépend des méthodes __bool__() et __len__().)

operator.truth(obj)

Renvoie True si obj est vrai, et False dans le cas contraire. Équivaut à utiliser le constructeur de bool.

operator.is_(a, b)

Renvoie a is b. Vérifie si les deux paramètres sont le même objet.

operator.is_not(a, b)

Renvoie a is not b. Vérifie si les deux paramètres sont deux objets distincts.

Les opérations mathématiques ou bit à bit sont les plus nombreuses :

operator.abs(obj)
operator.__abs__(obj)

Renvoie la valeur absolue de obj.

operator.add(a, b)
operator.__add__(a, b)

Renvoie a + ba et b sont des nombres.

operator.and_(a, b)
operator.__and__(a, b)

Renvoie le et bit à bit de a et b.

operator.floordiv(a, b)
operator.__floordiv__(a, b)

Renvoie a // b.

operator.index(a)
operator.__index__(a)

Renvoie a converti en entier. Équivaut à a.__index__().

operator.inv(obj)
operator.invert(obj)
operator.__inv__(obj)
operator.__invert__(obj)

Renvoie l’inverse bit à bit du nombre obj. Équivaut à ~obj.

operator.lshift(a, b)
operator.__lshift__(a, b)

Renvoie le décalage de b bits vers la gauche de a.

operator.mod(a, b)
operator.__mod__(a, b)

Renvoie``a % b``.

operator.mul(a, b)
operator.__mul__(a, b)

Renvoie a * ba et b sont des nombres.

operator.matmul(a, b)
operator.__matmul__(a, b)

Renvoie a @ b.

Nouveau dans la version 3.5.

operator.neg(obj)
operator.__neg__(obj)

Renvoie l’opposé de obj (-obj).

operator.or_(a, b)
operator.__or__(a, b)

Renvoie le ou bit à bit de a et b.

operator.pos(obj)
operator.__pos__(obj)

Renvoie la valeur positive de obj (+obj).

operator.pow(a, b)
operator.__pow__(a, b)

Renvoie a ** ba et b sont des nombres.

operator.rshift(a, b)
operator.__rshift__(a, b)

Renvoie le décalage de b bits vers la droite de a.

operator.sub(a, b)
operator.__sub__(a, b)

Renvoie a - b.

operator.truediv(a, b)
operator.__truediv__(a, b)

Renvoie a / b où 2/3 est 0.66 et non 0. Appelée aussi division « réelle ».

operator.xor(a, b)
operator.__xor__(a, b)

Renvoie le ou exclusif bit à bit de a et b.

Les opérations sur séquences (et pour certaines, sur correspondances) sont :

operator.concat(a, b)
operator.__concat__(a, b)

Renvoie a + ba et b sont des séquences.

operator.contains(a, b)
operator.__contains__(a, b)

Renvoie le résultat du test b in a. Notez que les opérandes sont inversées.

operator.countOf(a, b)

Renvoie le nombre d’occurrences de b dans a.

operator.delitem(a, b)
operator.__delitem__(a, b)

Renvoie la valeur de a à l’indice b.

operator.getitem(a, b)
operator.__getitem__(a, b)

Renvoie la valeur de a à l’indice b.

operator.indexOf(a, b)

Renvoie l’indice de la première occurrence de b dans a.

operator.setitem(a, b, c)
operator.__setitem__(a, b, c)

Affecte c dans a à l’indice b.

operator.length_hint(obj, default=0)

Renvoie une estimation de la taille de l’objet o. Tente d’abord de renvoyer la taille réelle, puis une estimation en appelant object.__length_hint__(), ou sinon la valeur par défaut.

Nouveau dans la version 3.4.

Le module operator définit aussi des fonctions pour la recherche générique d’attributs ou d’objets. Elles sont particulièrement utiles pour construire rapidement des accesseurs d’attributs à passer en paramètre à map(), sorted(), itertools.groupby() ou à toute autre fonction prenant une fonction en paramètre.

operator.attrgetter(attr)
operator.attrgetter(*attrs)

Renvoie un objet appelable qui récupère attr de son opérande. Si plus d’un attribut est demandé, renvoie un n-uplet d’attributs. Les noms des attributs peuvent aussi comporter des points. Par exemple :

  • Avec f = attrgetter('name'), l’appel f(b) renvoie b.name.
  • Avec f = attrgetter('name', 'date'), l’appel f(b) renvoie (b.name, b.date).
  • Après f = attrgetter('name.first', 'name.last'), l’appel f(b) renvoie (b.name.first, b.name.last).

Équivalent à :

def attrgetter(*items):
    if any(not isinstance(item, str) for item in items):
        raise TypeError('attribute name must be a string')
    if len(items) == 1:
        attr = items[0]
        def g(obj):
            return resolve_attr(obj, attr)
    else:
        def g(obj):
            return tuple(resolve_attr(obj, attr) for attr in items)
    return g

def resolve_attr(obj, attr):
    for name in attr.split("."):
        obj = getattr(obj, name)
    return obj
operator.itemgetter(item)
operator.itemgetter(*items)

Renvoie un objet appelable qui récupère item de l’opérande en utilisant la méthode __getitem__(). Si plusieurs item sont passés en paramètre, renvoie un n-uplet des valeurs récupérées. Par exemple :

  • Avec f = itemgetter(2), f(r) renvoie r[2].
  • Avec g = itemgetter(2, 5, 3), g(r) renvoie (r[2], r[5], r[3]).

Équivalent à :

def itemgetter(*items):
    if len(items) == 1:
        item = items[0]
        def g(obj):
            return obj[item]
    else:
        def g(obj):
            return tuple(obj[item] for item in items)
    return g

Les items en entrée peuvent être de n’importe quel type tant que celui-ci est géré par la méthode __getitem__() de l’opérande. Les dictionnaires acceptent toute valeur hachable. Les listes, n-uplets et chaînes de caractères acceptent un index ou une tranche :

>>> itemgetter(1)('ABCDEFG')
'B'
>>> itemgetter(1,3,5)('ABCDEFG')
('B', 'D', 'F')
>>> itemgetter(slice(2,None))('ABCDEFG')
'CDEFG'

Exemple d’utilisation de itemgetter() pour récupérer des champs spécifiques d’un n-uplet :

>>> inventory = [('apple', 3), ('banana', 2), ('pear', 5), ('orange', 1)]
>>> getcount = itemgetter(1)
>>> list(map(getcount, inventory))
[3, 2, 5, 1]
>>> sorted(inventory, key=getcount)
[('orange', 1), ('banana', 2), ('apple', 3), ('pear', 5)]
operator.methodcaller(name[, args...])

Renvoie un objet appelable qui appelle la méthode name de son opérande. Si des paramètres supplémentaires et/ou des paramètres nommés sont donnés, ils seront aussi passés à la méthode. Par exemple :

  • Avec f = methodcaller('name'), f(b) renvoie b.name().
  • Avec f = methodcaller('name', 'foo', bar=1), f(b) renvoie b.name('foo', bar=1).

Équivalent à :

def methodcaller(name, *args, **kwargs):
    def caller(obj):
        return getattr(obj, name)(*args, **kwargs)
    return caller

10.3.1. Correspondances entre opérateurs et fonctions

Le tableau montre la correspondance entre les symboles des opérateurs Python et les fonctions du module operator.

Opération Syntaxe Fonction
Addition a + b add(a, b)
Concaténation seq1 + seq2 concat(seq1, seq2)
Test d’inclusion obj in seq contains(seq, obj)
Division a / b truediv(a, b)
Division a // b floordiv(a, b)
Et bit à bit a & b and_(a, b)
Ou exclusif bit à bit a ^ b xor(a, b)
Inversion bit à bit ~ a invert(a)
Ou bit à bit a | b or_(a, b)
Exponentiation a ** b pow(a, b)
Identité a is b is_(a, b)
Identité a is not b is_not(a, b)
Affectation par index obj[k] = v setitem(obj, k, v)
Suppression par index del obj[k] delitem(obj, k)
Indexation obj[k] getitem(obj, k)
Décalage bit à bit gauche a << b lshift(a, b)
Modulo a % b mod(a, b)
Multiplication a * b mul(a, b)
Multiplication matricielle a @ b matmul(a, b)
Opposé - a neg(a)
Négation (logique) not a not_(a)
Valeur positive + a pos(a)
Décalage bit à bit droite a >> b rshift(a, b)
Affectation par tranche seq[i:j] = values setitem(seq, slice(i, j), values)
Suppression par tranche del seq[i:j] delitem(seq, slice(i, j))
Tranche seq[i:j] getitem(seq, slice(i, j))
Formatage de chaînes de caractères s % obj mod(s, obj)
Soustraction a - b sub(a, b)
Test de véracité obj truth(obj)
Ordre a < b lt(a, b)
Ordre a <= b le(a, b)
Égalité a == b eq(a, b)
Différence a != b ne(a, b)
Ordre a >= b ge(a, b)
Ordre a > b gt(a, b)

10.3.2. Inplace Operators

Beaucoup d’opérations ont une version travaillant « en-place ». Les fonctions listées ci-dessous fournissent un accès plus direct aux opérateurs en-place que la syntaxe Python habituelle ; par exemple, l’expression statement x += y équivaut à x = operator.iadd(x, y). Autrement dit, l’expression z = operator.iadd(x, y) équivaut à l’expression composée z = x; z += y.

Dans ces exemples, notez que lorsqu’une méthode en-place est appelée, le calcul et l’affectation sont effectués en deux étapes distinctes. Les fonctions en-place de la liste ci-dessous ne font que la première, en appelant la méthode en-place. La seconde étape, l’affectation, n’est pas effectuée.

Pour des paramètres non-mutables comme les chaînes de caractères, les nombres et les n-uplets, la nouvelle valeur est calculée, mais pas affectée à la variable d’entrée:

>>> a = 'hello'
>>> iadd(a, ' world')
'hello world'
>>> a
'hello'

For mutable targets such as lists and dictionaries, the inplace method will perform the update, so no subsequent assignment is necessary:

>>> s = ['h', 'e', 'l', 'l', 'o']
>>> iadd(s, [' ', 'w', 'o', 'r', 'l', 'd'])
['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']
>>> s
['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']
operator.iadd(a, b)
operator.__iadd__(a, b)

a = iadd(a, b) is equivalent to a += b.

operator.iand(a, b)
operator.__iand__(a, b)

a = iand(a, b) is equivalent to a &= b.

operator.iconcat(a, b)
operator.__iconcat__(a, b)

a = iconcat(a, b) is equivalent to a += b for a and b sequences.

operator.ifloordiv(a, b)
operator.__ifloordiv__(a, b)

a = ifloordiv(a, b) is equivalent to a //= b.

operator.ilshift(a, b)
operator.__ilshift__(a, b)

a = ilshift(a, b) is equivalent to a <<= b.

operator.imod(a, b)
operator.__imod__(a, b)

a = imod(a, b) is equivalent to a %= b.

operator.imul(a, b)
operator.__imul__(a, b)

a = imul(a, b) is equivalent to a *= b.

operator.imatmul(a, b)
operator.__imatmul__(a, b)

a = imatmul(a, b) is equivalent to a @= b.

Nouveau dans la version 3.5.

operator.ior(a, b)
operator.__ior__(a, b)

a = ior(a, b) is equivalent to a |= b.

operator.ipow(a, b)
operator.__ipow__(a, b)

a = ipow(a, b) is equivalent to a **= b.

operator.irshift(a, b)
operator.__irshift__(a, b)

a = irshift(a, b) is equivalent to a >>= b.

operator.isub(a, b)
operator.__isub__(a, b)

a = isub(a, b) is equivalent to a -= b.

operator.itruediv(a, b)
operator.__itruediv__(a, b)

a = itruediv(a, b) is equivalent to a /= b.

operator.ixor(a, b)
operator.__ixor__(a, b)

a = ixor(a, b) is equivalent to a ^= b.