IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Python, de zéro


précédentsommairesuivant

XXI. Pour tester les types

Le développeur Python pourra être amené parfois à devoir vérifier le type précis de ses variables. Cela peut être par exemple pour vérifier un paramètre reçu ou pour toutes autres raisons qui peuvent survenir dans la vie d’un projet.

Le premier réflexe sera alors d’utiliser la fonction type() pour comparer son résultat avec le type attendu.

Exemple :

 
Sélectionnez
1.
2.
3.
4.
5.
def carre(n):
    if type(n) not in (int, float):
        print("Erreur %s n’est pas un type int/float" % n)
        return None
    return n**2

Mais cette façon de faire se heurtera très rapidement à deux problèmes :

  • les chaînes peuvent être de plusieurs types (bytes ou str sous Python 3 et respectivement str ou unicode sous Python 2). Et dans chaque cas, les différents types ne sont pas (du point de vue Python) identiques ;
 
Sélectionnez
1.
2.
3.
4.
>>> type("xxx") == str
True
>>> type("xxx") == bytes
False
  • les objets peuvent hériter les uns des autres. Un objet voiture pourra par exemple hériter d’un objet véhicule. Or, si d’un point de vue naturel, une voiture est bien un véhicule, d’un point de vue Python ce n’en est pas un.
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
>>> class vehicule: pass
...
>>> class voiture(vehicule): pass
...
>>> v=voiture()
>>> type(v) == voiture
True
>>> type(v) == vehicule
False

Pour pallier ces problèmes, Python offre la fonction isinstance().

Cette fonction permet de lui passer soit le type à vérifier (sous forme de paramètre unique), soit un ensemble de types à vérifier (sous forme de tuple). Elle renverra alors True/False si le type de l’élément correspond/ne correspond pas au type (ou à un des types) demandé(s).

 
Sélectionnez
1.
2.
3.
4.
5.
def carre(n):
    if not isinstance(n, (int, float)):
        print("Erreur %s n’est pas un type int/float " % n)
        return None
    return n**2
 
Sélectionnez
1.
2.
3.
4.
>>> isinstance("xxx", str)
True
>>> isinstance(b"xxx", (str, bytes))
True

Cela semblera assez anodin comme possibilité (on aurait obtenu le même résultat avec type(v) in (typeX, typeY, typeZ)). Cependant, cette fonction offre le second avantage de pouvoir remonter l’héritage d’un objet. Et considèrera donc comme « vrai » si le type de l’objet correspond au type demandé ou à l’un de ses ascendants.

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
>>> class vehicule: pass
...
>>> class voiture(vehicule): pass
...
>>> class caravane(voiture): pass
...
>>> c=caravane()
>>> isinstance(c, caravane)
True
>>> isinstance(c, voiture)
True
>>> isinstance(c, vehicule)
True

La fonction issubclass() est analogue à la fonction isinstance() à ceci près que la première ne peut tester qu’une variable ; ce qui oblige alors à instancier l’objet dans une variable si l’on veut le vérifier ; alors que issubclass() peut tester directement un objet (une classe) sans avoir à l’instancier.

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
>>> class vehicule: pass
...
>>> class voiture(vehicule): pass
...
>>> class caravane(voiture): pass
...
>>> c=caravane()                       # Obligé d’instancier "caravane" dans une variable…
>>> isinstance(c, caravane)            # …pour pouvoir le vérifier avec "isinstance"
True
>>> issubclass(caravane, caravane)     # Alors qu’avec "issubclass" on n’est plus obligé
True
>>> issubclass(caravane, voiture)
True
>>> issubclass(caravane, vehicule)
True
>>> issubclass(voiture, caravane)
False
>>> issubclass(voiture, voiture)
True
>>> issubclass(voiture, vehicule)
True
>>> issubclass(vehicule, caravane)
False
>>> issubclass(vehicule, voiture)
False
>>> issubclass(vehicule, vehicule)
True

Et bien évidemment, tout comme isinstance(), la fonction issubclass() peut tester d'un seul appel plusieurs classes éventuelles (le test sera vrai si l’une des classes correspond).

 
Sélectionnez
1.
2.
3.
4.
>>> issubclass(vehicule, (caravane, voiture))
False
>>> issubclass(vehicule, (caravane, voiture, vehicule))
True
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
class LOTR:
    @classmethod
    def say(cls):
        if issubclass(cls, Magicien):
            print("Fuyez, pauvres fous... (et en plus c'est sans alcool) !!!")
        if issubclass(cls, Nain):
            print("Jamais je n'aurais pensé mourir aux côtés d'un elfe")
        if issubclass(cls, Elfe):
            print("Et que diriez-vous de mourir aux côtés d'un ami ?")

>>> class Magicien(LOTR): pass
...
>>> class Nain(LOTR): pass
...
>>> class Elfe(LOTR): pass
...
>>> Magicien.say()
Fuyez, pauvres fous... (et en plus c’est sans alcool) !!!
>>> Nain.say()
Jamais je n’aurais pensé mourir aux côtés d’un elfe
>>> Elfe.say()
Et que diriez-vous de mourir aux côtés d’un ami ?

précédentsommairesuivant

Copyright © 2022 Svear (svear@free.fr) Permission est accordée de copier, distribuer ou modifier ce document selon les termes de la « Licence de Documentation Libre GNU » (GNU Free Documentation License), version 1.1 ou toute version ultérieure publiée par la Free Software Foundation.