Hoe gebruik je python’s isinstance() op de juiste manier om te controleren of een variabele een getal is?

Ik heb een oude Python-code gevonden die zoiets deed als:

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

Zoals verwacht klaagt pep8over dit aanbevolen gebruik van isinstance().

Het probleem is nu dat de module numbersis toegevoegd in Python 2.6 en ik code moet schrijven die werkt met Python 2.5+

Dus if isinstance(var, Numbers.number)is geen oplossing.

Wat zou in dit geval de juiste oplossing zijn?


Antwoord 1, autoriteit 100%

In Python 2 kun je de module typesgebruiken:

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

Let op het gebruik van een tuple om te testen tegen meerdere typen.

Onder de motorkap is IntTypeslechts een alias voor int, enz.:

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

Het type complexvereist dat je python is gecompileerd met ondersteuning voor complexe getallen; als je hiervoor wilt waken, gebruik dan een try/behalve-blok:

>>> 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)
...

of als je de typen gewoon direct gebruikt:

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

In Python 3 hebben typesgeen standaard type aliassen meer, is complexaltijd ingeschakeld en is er niet langer een longvs intverschil, dus gebruik in Python 3 altijd:

NumberTypes = (int, float, complex)

Last but not least kunt u de numbers.Numbersabstract basistype(nieuw in Python 2.6) om ook aangepaste numerieke typen te ondersteunen die niet rechtstreeks afgeleid zijn van de bovenstaande typen:

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

Deze controle retourneert ook Truevoor decimal.Decimal()en fractions.Fraction()objecten.

Deze module gaat er wel van uit dat het type complexis ingeschakeld; je krijgt een importfout als dit niet het geval is.


Antwoord 2, autoriteit 17%

Python 2 ondersteunt vier typen voor getallen int,float, longen complexen python 3.xondersteunt 3:int, floaten 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

Antwoord 3, autoriteit 3%

Afhankelijk van wat je gebruikt, kan dit in eenden typeneen betere benadering zijn ( het is zekervaakaanbevolen). Het probleem met de aanpak van Martijn Pieters is dat je altijd een aantal soorten nummers uit je lijst zult missen. Uit mijn hoofd zal je code niet werken met: sympy rationale getallen, willekeurige precisie gehele getallen en elke implementatie van complexe getallen.

Een alternatief is om een ​​functie als deze te schrijven:

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

Deze code zou moeten werken met elke redelijke implementatie van een nummer. Natuurlijk is er een groot nadeel: het zal ook werken met een onredelijke implementatie van veel niet-getallen (d.w.z. als de plus-operator overbelast is en een geheel getal accepteert).

Een ander alternatief (afhankelijk van waarom je moet weten of iets een getal is) is om gewoon aan te nemen dat het een getal is, en als dat niet het geval is, worden er fouten gegenereerd door elk stukje van de code dat een getal vereist.

p>

Ik zeg niet dat deze benaderingen altijd beter zijn (in tegenstelling tot sommige mensen…), alleen dat ze het overwegen waard zijn.

Other episodes