Ik heb een oude Python-code gevonden die zoiets deed als:
if type(var) is type(1):
...
Zoals verwacht klaagt pep8
over dit aanbevolen gebruik van isinstance()
.
Het probleem is nu dat de module numbers
is 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 types
gebruiken:
>>> 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 IntType
slechts een alias voor int
, enz.:
>>> isinstance(var, (int, long, float, complex))
True
Het type complex
vereist 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 types
geen standaard type aliassen meer, is complex
altijd ingeschakeld en is er niet langer een long
vs int
verschil, dus gebruik in Python 3 altijd:
NumberTypes = (int, float, complex)
Last but not least kunt u de numbers.Numbers
abstract 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 True
voor decimal.Decimal()
en fractions.Fraction()
objecten.
Deze module gaat er wel van uit dat het type complex
is ingeschakeld; je krijgt een importfout als dit niet het geval is.
Antwoord 2, autoriteit 17%
Python 2 ondersteunt vier typen voor getallen int
,float
, long
en complex
en python 3.x
ondersteunt 3:int
, float
en 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.