2015-07-02 4 views
3

Мы все сделали этот вид ошибки в Python:избежать ошибки, сравнивая число и строку

if (number < string): 

питон молча принимает это и просто дает неправильный вывод.

Благодарите доброту python 3, наконец, предупреждает нас. Но в некоторых случаях требуется python 2.7. Есть ли способ в python 2.7 защищать эту ошибку, кроме как «просто быть осторожным» (что мы все знаем, не работает в 100% случаев)?

+3

Нет, нет, поэтому они поменяли его на Python 3.x. При написании в Python 2.7 просто будьте осторожны :) – CoryKramer

+0

Спасибо всем за ваши ответы. –

ответ

3

Вы можете явно преобразовать оба номера в int. Строка будет преобразована, и число не будет выполнено (это уже int). Таким образом, это избавляет вас от необходимости начать вспоминать, какой тип значения число имеет:

a = 11 
b = "2" 
print a > b # prints False, which isn't what you intended 
print int(a) > int(b) # prints True 

EDIT:
Как было отмечено в комментариях, вы не можете предположить число является целым числом. Однако, применяя тот же поезд, хотя с соответствующей функцией - float должна хорошо работать:

a = 11 
b = "2" 
print a > b # prints False, which isn't what you intended 
print float(a) > float(b) # prints True 
+0

Вот что я хотел предложить, но что, если это 'float', а не' int'? OP должен будет иметь все комбинации 'int' и' float' для 'a' и' b'. – DeepSpace

+0

«Число не будет выполнено (это уже int)» - откуда вы это знаете? 'int (" 1.0 ")' является ошибкой. –

+0

@ DeepSpace хорошая точка - лучше просто использовать 'float' - см. Мой отредактированный ответ. – Mureinik

0

Если вы действительно, действительно хотят быть 100% уверены, что сравнение строк и Интс невозможно, вы можете перегрузить __builtin__.int__builtin__.float и т. д. по необходимости), чтобы запретить сравнение целых чисел (и плавающих и т. д.) со строками. Это будет выглядеть следующим образом:

import __builtin__ 

class no_str_cmp_int(int): 
    def __lt__(self,other): 
     if type(other) is str: 
      raise TypeError 
     return super.__lt__(other) 
    def __gt__(self,other): 
     if type(other) is str: 
      raise TypeError 
     return super.__gt__(other) 
    # implement __gte__, __lte__ and others as necessary 

# replace the builtin int method to disallow string comparisons 
__builtin__.int = no_str_cmp_int 

x = int(10) 

Затем, если вы попытаетесь сделать что-то вроде этого, вы получите эту ошибку:

>>> print x < '15' 

Traceback (most recent call last): 
    File "<pyshell#15>", line 1, in <module> 
    print x < '15' 
    File "tmp.py", line 7, in __lt__ 
    raise TypeError 
TypeError 

Существует большой нюанс такого подхода, однако. Он заменяет только функцию int, поэтому каждый раз, когда вы создавали int, вам нужно передать ее через функцию, как это было в объявлении x выше. Литералы будут по-прежнему быть оригинальным типом int, и насколько я знаю, нет способа изменить это. Однако, если вы правильно создадите эти объекты, они будут продолжать работать со 100% гарантией, которую вы желаете.

+0

Я пытался сделать что-то подобное, это заставило мой ipython взорваться! – BlackBear

-1

Вы можете проверить, если каждая переменная является INT, как это:

if (isinstance(number, int) and isinstance(string, int)): 
    if (number < string): 
     Do something 
    else: 
     Do something else 
else : 
    print "NaN" 

* Edit: Чтобы проверить поплавок тоже код должен быть:

if (isinstance(number, (int,float)) and isinstance(string, (int,float))): 
+0

Опять же, см. Комментарии к верхнему ответу. Что, если число является плавающей? По вашему коду некоторые очень важные цифры, такие как pi и константа Эйлера, «не являются числом», потому что они не являются целыми! –

0

Просто преобразовать строку или любой тип данных, который нужно поместить первым. Если два типа данных совпадают, тогда мы можем их сравнить.

Предположим,

a = "10" 
b= 9.3 
c=9 

Мы хотим добавить, b, c .. Так,

Таким образом, правильный способ добавить эти три, чтобы преобразовать их в тот же тип данных, а затем добавить ,

a = float(a) 
b = float(b) 
c = float(c) 

print a+b+c