1172 votes

Vérifier si une variable est un nombre entier ou non

Comment vérifier si une variable est un nombre entier ?

3 votes

@Hulk : Vous semblez avoir l'impression que type est la bonne façon de faire. Ce n'est (presque certainement) pas le cas.

0 votes

@katrielalex : s'il avait choisi ma réponse comme étant la bonne ne signifie pas que Hulk avait l'impression que vous mentionnez. Il y a aussi le ValueError manière d'exception mentionnée AVANT le type() .

0 votes

@Hulk : Honnêtement, je ne fais pas campagne pour que vous acceptiez ma réponse - s'il vous plaît, n'hésitez pas à la changer pour Ashish ; il a fourni une réponse parfaitement valide et techniquement correcte. Je voulais juste m'assurer que vous aviez lu le reste des conseils sur cette page.

1422voto

katrielalex Points 40655

Si vous devez le faire, faites

isinstance(<var>, int)

à moins que vous ne soyez en Python 2.x, auquel cas vous voulez

isinstance(<var>, (int, long))

Ne pas utiliser type . Ce n'est presque jamais la bonne réponse en Python, car cela bloque toute la flexibilité du polymorphisme. Par exemple, si vous sous-classez int votre nouvelle classe devrait être enregistrée comme une int qui type ne fera pas l'affaire :

class Spam(int): pass
x = Spam(0)
type(x) == int # False
isinstance(x, int) # True

Ceci est conforme au fort polymorphisme de Python : vous devez autoriser tout objet qui se comporte comme un objet de type int au lieu d'exiger qu'il en soit un.

MAIS

La mentalité classique de Python, cependant, est que c'est il est plus facile de demander le pardon que la permission . En d'autres termes, ne vérifiez pas si x est un entier ; supposez que c'est le cas et attrapez les résultats de l'exception si ce n'est pas le cas :

try:
    x += 1
except TypeError:
    ...

Cette mentalité est lentement dépassée par l'utilisation de classes de base abstraites qui vous permettent d'enregistrer exactement les propriétés que votre objet doit avoir (additionner ? multiplier ? doubler ?) en le faisant hériter d'une classe spécialement construite. Ce serait la meilleure solution, puisqu'elle permettrait à exactement ces objets avec les attributs nécessaires et suffisants, mais vous devrez lire les docs sur la façon de l'utiliser.

8 votes

Hmm. Je m'interroge sur la partie MAIS ! La vérification correcte et claire des données lors de l'entrée d'une méthode (par exemple, le démarrage, avant de commencer à faire quoi que ce soit avec une variable) n'est-elle pas une bonne pratique en Python, comme elle devrait l'être dans toute programmation ? Ainsi, par exemple, avant de donner des données à une requête de base de données lorsque je veux récupérer un objet par son identifiant, qui est un entier, je vérifie si l'entrée est réellement un entier et utilisable avant de la transmettre à la couche de base de données.

3 votes

@Henning Je crois que la réponse "pythonique" serait "non". Par le typage en canard, c'est seulement un problème si cela causerait une erreur au niveau de la base de données, et il n'y a aucun moyen de dire si c'est le cas en se basant sur le type. Ainsi, selon la section BUT, le meilleur plan d'action serait de laisser la couche base de données lancer l'erreur et de s'en occuper quand elle se présente. Tout ce qui a un comportement compatible peut être utilisé ; le type int / long est un excellent exemple ; que se passe-t-il si quelqu'un a un programme de short type ? Il est compatible avec int et la base de données, mais votre code ne l'accepterait pas s'il vérifiait le type.

6 votes

@katrielalex Cela peut vous paraître stupide mais pouvez-vous m'expliquer pourquoi isinstance( True, int ) renvoie Vrai.

159voto

saroele Points 748

Toutes les réponses proposées jusqu'à présent semblent passer à côté du fait qu'un double (les flottants en python sont en fait des doubles) peut aussi être un entier (s'il n'a rien après la virgule). J'utilise la fonction intégrée is_integer() sur les doubles pour vérifier cela.

Exemple (pour faire quelque chose chaque xième fois dans une boucle for) :

for index in range(y): 
    # do something
    if (index/x.).is_integer():
        # do something special

Edit :

Vous pouvez toujours convertir en flottant avant d'appeler cette méthode. Les trois possibilités :

>>> float(5).is_integer()
True
>>> float(5.1).is_integer()
False
>>> float(5.0).is_integer()
True

Sinon, vous pouvez d'abord vérifier si c'est un int comme l'a dit Agostino :

def is_int(val):
    if type(val) == int:
        return True
    else:
        if val.is_integer():
            return True
        else:
            return False

2 votes

Avez-vous un lien vers une documentation sur ce sujet ? is_integer fonction ? Je n'en trouve pas.

4 votes

Il n'y a pas grand chose, mais voici la documentation officielle : docs.python.org/2/library/stdtypes.html#float.is_integer

5 votes

C'est bon à savoir. Bien que, c'est un float Il ne s'agit donc pas d'une fonction à usage général qui peut être appliquée à n'importe quel type pour déterminer s'il s'agit d'un nombre entier.

70voto

Scott Griffiths Points 8867

Si vous vraiment doivent être vérifiés, il est préférable d'utiliser classes de base abstraites plutôt que des classes concrètes. Pour un nombre entier, cela signifie :

>>> import numbers
>>> isinstance(3, numbers.Integral)
True

Cela ne limite pas la vérification à seulement int ou simplement int y long mais permet également à d'autres types définis par l'utilisateur qui se comportent comme des entiers de fonctionner.

3 votes

isinstance(Fraction(5,1), numbers.Integral) Faux. C'est bien ça ?

6 votes

@endolith : Ma réponse (et les autres) disent si le type de la variable est un entier plutôt que si la variable elle-même pourrait être convertie en entier sans perdre d'information. Donc oui, votre exemple est False de la même manière que l'on vérifie l'"intégrité" de l'échantillon. 5.00 serait.

3 votes

... mais je suppose que l'on pourrait aussi faire un test du type "cet objet est-il exactement représentable sous forme d'un nombre entier", comme suit type(f)(int(f)) == f .

40voto

Matt Joiner Points 29194
>>> isinstance(3, int)
True

Voir aquí pour plus.

Notez que cela n'est pas utile si vous recherchez int -des attributs similaires. Dans ce cas, vous pouvez également vérifier si long :

>>> isinstance(3L, (long, int))
True

J'ai vu des vérifications de ce type par rapport à un type de tableau/index dans les sources Python, mais je ne pense pas que cela soit visible en dehors du C.

Réponse du Token SO : Etes-vous sûr que vous devez vérifier son type ? Soit vous ne passez pas un type que vous ne pouvez pas gérer, soit vous n'essayez pas d'être plus malin que les réutilisateurs potentiels de votre code, ils peuvent avoir une bonne raison de ne pas passer un int à votre fonction.

0 votes

+1 : Après tout, decimal.Decimal y fractions.Rational fonctionne souvent là où vous avez si soigneusement vérifié pour int . La vérification du type à l'avance empêche légal, approprié l'utilisation. Il n'empêche aucun problème.

1 votes

J'avais une variable dans un dictionnaire, il faut donc faire un contrôle de type dans ce cas.

2 votes

@Hulk : Pourquoi ce cas est-il spécial ?

31voto

Parsa Points 259

Pourquoi ne pas essayer quelque chose comme :

if x%1 == 0:

9 votes

-1 parce que ce n'est pas un code que je voudrais voir en production ou par mes coéquipiers. Il cache votre intention. La plupart des autres réponses ici sont beaucoup plus explicites et devraient être préférées.

26 votes

@Dennis : mais cela fonctionne aussi pour les flottants dont la partie décimale est égale à zéro. Vous pouvez l'envelopper dans une fonction et ce sera explicite.

0 votes

Et si x n'est même pas un nombre, mais une chaîne de caractères ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X