1175 Stimmen

Prüfung, ob eine Variable eine ganze Zahl ist oder nicht

Wie prüfe ich, ob eine Variable eine ganze Zahl ist?

0 Stimmen

@katrielalex: Wenn er meine Antwort als die richtige gewählt hat, bedeutet das nicht, dass Hulk den von Ihnen erwähnten Eindruck hatte. Es gibt auch die ValueError Ausnahmemöglichkeit, die VOR der type() .

0 Stimmen

@Hulk: Ich will wirklich nicht dafür werben, dass Sie meine Antwort akzeptieren - Sie können sie gerne an Ashish zurückgeben; er hat eine absolut gültige und technisch korrekte Antwort gegeben. Ich wollte nur sicherstellen, dass Sie auch den Rest der Ratschläge auf dieser Seite gelesen haben.

0 Stimmen

@katrielalex: Ashish hatte Recht, aber die Kodierungsszenarien brauchten die Ausnahmeklausel, und so habe ich meine Antwort geändert, nichts für ungut, Ashish.

1422voto

Katriel Punkte 115208

Wenn Sie dies tun müssen, tun Sie

isinstance(<var>, int)

es sei denn, Sie arbeiten mit Python 2.x. In diesem Fall sollten Sie

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

Nicht verwenden type . Das ist in Python fast nie die richtige Antwort, da es die ganze Flexibilität der Polymorphie blockiert. Wenn Sie zum Beispiel eine Unterklasse int sollte sich Ihre neue Klasse als int die type nicht ausreichen wird:

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

Dies entspricht dem starken Polymorphismus von Python: Sie sollten jedes Objekt erlauben, das sich wie ein int anstatt eine solche vorzuschreiben.

BUT

Die klassische Python-Mentalität ist jedoch, dass es es ist einfacher, um Vergebung zu bitten als um Erlaubnis . Mit anderen Worten: Prüfen Sie nicht, ob x eine ganze Zahl ist; nehmen Sie an, dass dies der Fall ist und fangen Sie die Ausnahmeergebnisse ab, wenn dies nicht der Fall ist:

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

Diese Mentalität wird langsam durch die Verwendung von abstrakte Basisklassen die es Ihnen ermöglichen, genau zu registrieren, welche Eigenschaften Ihr Objekt haben soll (Addieren? Multiplizieren? Verdoppeln?), indem Sie es von einer speziell konstruierten Klasse erben lassen. Das wäre die beste Lösung, da sie Folgendes ermöglicht genau diese Objekte mit den notwendigen und hinreichenden Attributen, aber Sie müssen in den Dokumenten nachlesen, wie sie zu verwenden sind.

8 Stimmen

Hm. Ich wundere mich über den ABER-Teil! Ist eine ordnungsgemäße und eindeutige Datenüberprüfung bei der Methodeneingabe (z.B. Start, bevor eine Variable bearbeitet wird) nicht eine gute Praxis in Python, wie sie generell in jeder Programmierung sein sollte? So prüfe ich zum Beispiel, bevor ich Daten an eine Datenbankabfrage weitergebe, wenn ich ein Objekt nach seiner ID abrufen will, die eine ganze Zahl ist, ob die Eingabe tatsächlich eine ganze Zahl ist und verwendet werden kann, bevor ich sie an die Datenbankschicht weitergebe.

3 Stimmen

@Henning Ich glaube, die "pythonische" Antwort wäre "nein". Durch die Enten-Typisierung ist es nur ein Problem, wenn es einen Fehler in der Datenbankebene verursachen würde, und es gibt keine Möglichkeit, anhand des Typs festzustellen, ob das der Fall ist. Laut dem Abschnitt BUT wäre es also am besten, den Fehler einfach von der Datenbankebene auslösen zu lassen und ihn zu behandeln, wenn er auftritt. Alles mit kompatiblem Verhalten könnte verwendet werden; die int / long Problem ist ein großartiges Beispiel: Was ist, wenn jemand eine benutzerdefinierte short Typ? Es ist kompatibel mit int und die Datenbank, aber Ihr Code würde es nicht akzeptieren, wenn er den Typ überprüfen würde.

6 Stimmen

@katrielalex Das klingt vielleicht blöd für dich, aber kannst du mir erklären, warum das isinstance( True, int ) gibt True zurück.

196voto

endolith Punkte 23212

Hier ist eine Zusammenfassung der verschiedenen Methoden, die hier erwähnt werden:

  • int(x) == x
  • try x = operator.index(x)
  • isinstance(x, int)
  • isinstance(x, numbers.Integral)

und hier ist, wie sie auf eine Vielzahl von numerischen Typen, die Integer-Wert haben gelten:

Table of methods for checking whether Python numerical types are integers

Wie Sie sehen können, sind sie nicht zu 100 % konsistent. Bruch und Rational sind begrifflich dasselbe, aber man liefert eine .index() Methode und die andere nicht. Komplexe Typen werden nicht gerne in int konvertiert, auch wenn der Realteil ganzzahlig und der Imaginärteil 0 ist.

( np.int8|16|32|64(5) bedeutet, dass np.int8(5) , np.int32(5) usw. verhalten sich alle identisch)

0 Stimmen

Ihr sympy.Rational Test nicht ganz das tut, was Sie denken, denn sympy.Rational(5) wertet eine Instanz von sympy.Integer . Jede Operation, die eine Rationale mit einem ganzzahligen Wert erzeugen würde, erzeugt stattdessen eine Ganzzahl.

0 Stimmen

@user2357112 Wieso ist das nicht "das, was ich denke"?

0 Stimmen

Sie sagen sympy.Rational unterstützt operator.index aber das ist nicht der Fall. Was vor sich geht, ist, dass sympy schaltet aggressiv auf spezifischere Typen um. sympy.Rational(5) passt nicht wirklich in den Unterabschnitt "rational" der Tabelle.

160voto

saroele Punkte 8631

Alle bisher vorgeschlagenen Antworten scheinen die Tatsache zu übersehen, dass ein Double (Floats in Python sind eigentlich Doubles) auch eine Ganzzahl sein kann (wenn es nichts nach dem Dezimalpunkt hat). Ich verwende die eingebaute is_integer() Methode auf Doppelgänger, um dies zu überprüfen.

Beispiel (um etwas jedes x-te Mal in einer for-Schleife zu tun):

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

Edit:

Sie können vor dem Aufruf dieser Methode immer in einen Float konvertieren. Die drei Möglichkeiten:

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

Andernfalls könnten Sie zunächst prüfen, ob es sich um einen int handelt, wie Agostino sagte:

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

2 Stimmen

Haben Sie einen Link zur Dokumentation für diese is_integer Funktion? Ich kann keine finden.

4 Stimmen

Es gibt nicht viel, aber hier ist die offizielle Dokumentation: docs.python.org/2/library/stdtypes.html#float.is_integer

5 Stimmen

Das ist gut zu wissen. Obwohl, es ist ein float Methode, es handelt sich also nicht um eine allgemeine Funktion, die auf jeden Typ angewendet werden kann, um festzustellen, ob es sich um eine ganze Zahl handelt.

70voto

Scott Griffiths Punkte 20629

Wenn Sie wirklich überprüfen müssen, dann ist es besser, die abstrakte Basisklassen und nicht konkrete Klassen. Für eine ganze Zahl würde das bedeuten:

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

Dies beschränkt die Prüfung nicht nur auf int oder einfach int y long , aber auch andere benutzerdefinierte Typen, die sich wie ganze Zahlen verhalten, können funktionieren.

3 Stimmen

isinstance(Fraction(5,1), numbers.Integral) Falsch. Ist das richtig?

6 Stimmen

@endolith: Meine Antwort (und die der anderen) besagt, ob der Typ der Variablen eine ganze Zahl ist, und nicht, ob die Variable selbst in eine ganze Zahl umgewandelt werden kann, ohne dass Informationen verloren gehen. Also ja, Ihr Beispiel ist False in der gleichen Weise wie die Überprüfung der "Integrität" von 5.00 wäre.

3 Stimmen

... aber ich nehme an, Sie könnten auch einen "Ist dieses Objekt genau als Ganzzahl darstellbar"-Test durchführen, etwa nach dem Muster type(f)(int(f)) == f .

40voto

Matt Joiner Punkte 105454
>>> isinstance(3, int)
True

Ver aquí für mehr.

Beachten Sie, dass dies nicht hilfreich ist, wenn Sie nach int -ähnlichen Eigenschaften. In diesem Fall sollten Sie auch prüfen, ob long :

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

Ich habe Prüfungen dieser Art gegen ein Array/Index-Typ in der Python-Quelle gesehen, aber ich glaube nicht, dass das außerhalb von C sichtbar ist.

Token SO Antwort: Sind Sie sicher, dass Sie seinen Typ überprüfen sollten? Übergeben Sie entweder keinen Typ, mit dem Sie nicht umgehen können, oder versuchen Sie nicht, Ihre potenziellen Code-Wiederverwender auszutricksen, denn sie könnten einen guten Grund haben, Ihrer Funktion keinen int zu übergeben.

0 Stimmen

+1: Immerhin, decimal.Decimal y fractions.Rational funktioniert oft dort, wo Sie so sorgfältig geprüft haben, ob int . Schriftprüfung im Voraus verhindert legal, angemessen verwenden. Es verhindert keine Probleme.

1 Stimmen

Ich hatte eine Variable in einem Wörterbuch, so dass ich in diesem Fall eine Typenprüfung durchführen musste

2 Stimmen

@Hulk: Warum ist dieser Fall besonders?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X