Question Comment utiliser correctement isinstance () de python pour vérifier si une variable est un nombre?


J'ai trouvé un ancien code Python qui faisait quelque chose comme:

if type(var) is type(1):
   ...

Comme prévu, pep8 se plaint de cette recommandation de l'utilisation de isinstance().

Maintenant, le problème est que le numbers module a été ajouté dans Python 2.6 et j'ai besoin d'écrire du code qui fonctionne avec Python 2.5+

Alors if isinstance(var, Numbers.number) n'est pas une solution.

Quelle serait la solution appropriée dans ce cas?


35
2018-06-26 09:53


origine


Réponses:


Vous pouvez utiliser le types module:

>>> import types
>>> var = 1
>>> NumberTypes = (types.IntType, types.LongType, types.FloatType, types.ComplexType)
>>> isinstance(var, NumberTypes)
True

Notez l'utilisation d'un tuple pour tester plusieurs types.

Sous la capuche, IntType est juste un alias pour int, etc.:

>>> isinstance(var, (int, long, float, complex))
True

le complex type nécessite que votre python ait été compilé avec la prise en charge de nombres complexes; si vous voulez garder pour cela utiliser un bloc try / except:

>>> try:
...     NumberTypes = (types.IntType, types.LongType, types.FloatType, types.ComplexType)
... except AttributeError:
...     # No support for complex numbers compiled
...     NumberTypes = (types.IntType, types.LongType, types.FloatType)
...

ou si vous utilisez simplement les types directement:

>>> try:
...     NumberTypes = (int, long, float, complex)
... except NameError:
...     # No support for complex numbers compiled
...     NumberTypes = (int, long, float)
...

Last but not least, vous pouvez utiliser le numbers.Numbers type de base abstrait (nouveau dans Python 2.6) pour prendre également en charge les types numériques personnalisés qui ne dérivent pas directement des types ci-dessus:

>>> import numbers
>>> isinstance(var, numbers.Number)
True

Ce module suppose que le complex le type est activé vous obtiendrez une erreur d'importation si ce n'est pas le cas.


86
2018-06-26 09:57



Python 2 prend en charge quatre types pour les nombres int,float, long et complexet python 3.x prend en charge 3:int, float et complex

>>> num = 10
>>> if isinstance(num, (int, float, long, complex)): #use tuple if checking against multiple types
      print('yes it is a number')

yes it is a number
>>> isinstance(num, float)   
False
>>> isinstance(num, int)
True
>>> a = complex(1, 2)
>>> isinstance(a, complex)
True

15
2018-06-26 09:57



Selon ce que vous utilisez dans Dactylographie pourrait être une meilleure approche (c'est certainement  communément  conseillé). Le problème avec l'approche de Martijn Pieters est que vous manquerez toujours certains types de numéros de votre liste. Au sommet de ma tête, votre code ne fonctionnera pas avec: les nombres rationnels sympy, les entiers de précision arbitraires et toute implémentation de nombres complexes.

Une alternative consiste à écrire une fonction comme ceci:

def is_number(thing):
    try:
        thing + 1
        return True
    except TypeError:
        return False

Ce code devrait fonctionner avec toute implémentation raisonnable d'un nombre. Bien sûr, il y a un inconvénient majeur: il fonctionnera également avec une implémentation déraisonnable de beaucoup de non-nombres (c.-à-d. Si l'opérateur plus est surchargé et accepte un entier).

Une autre alternative (selon que vous avez besoin de savoir si quelque chose est un nombre) consiste à supposer qu'il s'agit d'un nombre, et si ce n'est pas le cas, les erreurs seront déclenchées par le code qui requiert un numéro.

Je ne dis pas que ces approches sont toujours meilleures (contrairement à certaines personnes…) mais qu’elles valent la peine d’être prises en compte.


2
2017-10-03 12:42