2010-11-15 8 views
123

In Java die numerischen Typen alle stammen von Anzahl, so würde ichWie kann ich überprüfen, ob mein Python-Objekt eine Zahl ist?

(x instanceof Number). 

verwendet Was ist der Python-äquivalent?

+1

Für eine bessere Antwort zu arbeiten, siehe Alex Martelli Antwort auf die gleiche Frage. –

+1

Nicht wirklich ein Duplikat, der andere ist ein sehr spezifischer Fall dieser Frage (überprüfen Sie, ob etwas eine Zahl in einem Vektor ist), und die meisten der gewählten Antworten beziehen sich wirklich auf dieses Detail. –

+0

Multiplizieren Sie x mit Null. Wenn das Ergebnis etwas anderes als Null ist, dann ist x keine Zahl, siehe: https://stackoverflow.com/a/44418960/3419693 – shrewmouse

Antwort

160

In neueren Python-Versionen (2.6+, in älteren Versionen, die Sie ziemlich begrenzt sind für ein paar hartkodierte Typen Überprüfung), ist der richtige Weg zu testen, ob Ihre Variable eine Instanz von numbers.Number ist:

>>> import numbers 
>>> import decimal 
>>> [isinstance(x, numbers.Number) for x in (0, 0.0, 0j, decimal.Decimal(0))] 
[True, True, True, True] 

Diese ABCs verwendet und wird für alle Build-in-Nummer artigen Klassen arbeiten, und auch für alle Klassen von Drittanbietern, wenn sie ihr Salz wert sind (registriert als Unterklassen des Number ABC). In vielen Fällen sollten Sie sich jedoch keine Gedanken über die manuelle Überprüfung machen - Python ist ducktypiert und das Mischen einiger kompatibler Typen funktioniert normalerweise, aber es wird eine Fehlermeldung erscheinen, wenn eine Operation keinen Sinn ergibt (4 - "1") das wird selten wirklich benötigt. Es ist nur ein Bonus, den Sie hinzufügen können, wenn Sie dieses Modul beenden, um andere mit Implementierungsdetails nicht zu belästigen.

+3

Kleiner Kommentar, Sie können leicht gebrannt werden, wenn Sie versehentlich versuchen, einen Vergleich mit Objekten verschiedener Typen durchzuführen, da dann die Typen der Objekte als Strings verglichen werden. –

+0

Dies wird zur akzeptierten Antwort, da Python 2.5 weit in Ungnade gefallen ist. –

+3

Dies ergibt ein falsches positives Ergebnis, wenn Sie einen booleschen Wert übergeben: 'isinstance (True, numbers.Number)' gibt 'True' zurück, obwohl 'True' eindeutig keine Zahl ist. –

2

So funktioniert Python nicht wirklich. Benutze es einfach wie eine Nummer, und wenn dir jemand etwas übergibt, das keine Nummer ist, scheitere. Es liegt in der Verantwortung des Programmierers, die richtigen Typen zu übergeben.

+0

Verwenden Sie ausdrücklich 'except TypeError:'. Ausnahmen sind jedoch relativ teuer. – JAL

+7

... aber nur wenn sie ausgelöst werden. Im "normalen" Fall sind sie billiger als eine "if" -Anweisung. –

+7

nicht immer so einfach, manchmal unterstützen beide Typen die Schnittstelle, aber Sie möchten mit ihnen anders umgehen.Stellen Sie sich eine Reduzierungsfunktion vor, die Zahlen hinzufügen, aber keine Ketten verketten soll. –

127

ich denke, das würde funktionieren:

isinstance(x, (int, long, float, complex))

+2

Danke, das ist, was am Ende für mich in Jython funktioniert (das ist Python 2.5, also hat es nicht das Paket "Nummern"). Und ja, ich habe einen echten Grund, das Tippen zu unterbrechen. Ich muss Saiten und Zahlen anders behandeln. –

+6

'isinstance (Dezimal (10), (int, long, float, complex))' gibt 'False'. -1 – jpmc26

+4

Funktioniert nicht mit Python 3 (Name 'lang' ist nicht definiert) –

1

Sicher können Sie isinstance verwenden, aber beachten Sie, dass dies nicht funktioniert, wie Python funktioniert. Python ist eine Ente typisierte Sprache. Sie sollten Ihre Typen nicht explizit überprüfen. A TypeError wird ausgelöst, wenn der falsche Typ übergeben wurde.

Also nehmen Sie an, es ist ein int. Ärgere dich nicht zu überprüfen.

+0

Wie bereits erwähnt, besteht der ganze Sinn der Duck-Typisierung darin, Methodenüberladung und Methodenpolymorphie in derselben Klasse zuzulassen. – cowbert

37

Verwenden Sie Number aus dem numbers Modul, um isinstance(n, Number) zu testen (verfügbar seit 2.6).

isinstance(n, numbers.Number) 

Hier ist es in Aktion mit verschiedenen Arten von Zahlen und einer Nicht-Nummer:

>>> from numbers import Number 
... from decimal import Decimal 
... from fractions import Fraction 
... for n in [2, 2.0, Decimal('2.0'), complex(2,0), Fraction(2,1), '2']: 
...  print '%15s %s' % (n.__repr__(), isinstance(n, Number)) 
       2 True 
      2.0 True 
Decimal('2.0') True 
     (2+0j) True 
Fraction(2, 1) True 
      '2' False 

Dies ist natürlich, im Gegensatz zu Ente eingeben. Wenn Sie sich mehr darum sorgen, wie ein Objekt sich verhält und nicht, was es ist, führen Sie Ihre Operationen so aus, als hätten Sie eine Nummer und verwenden Sie Ausnahmen, um Ihnen etwas anderes zu sagen.

+7

Die Strategie "ob es eine Ausnahme gibt" ist oft unwirksam. Python ist ein bisschen aggressiv, wenn es um arithmetische Operationen für alle Arten von nicht-arithmetischen Dingen geht - nur weil ein Objekt '+' oder '*' zulässt, bedeutet das nicht, dass es irgendetwas wie eine Zahl ist. –

-9

es scheint

isinstance(TheNumber, (int,float, ...) 
+7

Downvoted, weil dies ein Duplikat einer bereits geposteten Antwort ist und es wurde * fast zwei Jahre * nach der Frage hinzugefügt. –

Verwandte Themen