2015-01-19 3 views
7

В javascript есть строгие операторы сравнения op1 === op2 и op1 !== op2, которые будут сравнивать как тип, так и значение. Есть ли питонический способ достижения того же?Строгое сравнение

До сих пор я только смог придумать со следующими запутанных условными:

isinstance(op1, type(op2)) and isinstance(op2, type(op1)) and op1 == op2 

и

not isinstance(op1, type(op2)) or not isinstance(op2, type(op1)) or op1 != op2 
+4

Нет, вы не можете проверить только личность 'is' (ссылка на тот же объект) или равенство' == '(которое опирается на реализацию магического метода' __eq__'). – jonrsharpe

+2

@jonrsharpe, и если вы используете '! =' Не забывайте о методе магии '__ne__'. –

ответ

7

Ваш подход будет действительно проверить как значение и тип. В Python нет другого оператора.

Это было сказано, во многих случаях это не то, что вы хотите - в философии Питона любой объект, который ведет себя как утка, следует рассматривать как утку. Вам часто не нужны только словари, вы хотите «объекты, подобные отображению», и так далее - пока объект может использоваться для конкретной задачи, тогда код должен его принять.

2

Сравнительный коэффициент Python по большей части всегда строгий.

Например:

Python

0 == '0' # False 
0 == '' # False 

Javascript

0 == '0' //True 
0 === '0' //False 
0 == '' //True 
0 === '0' //False 
+1

Случаи, о которых мне нужно было беспокоиться о часто встречающихся логических типах: '1 == True # True', тогда как в javascript' 1 === true // false' – RPGillespie

+2

@RPGillespie Вы всегда можете использовать оператор 'is' для True и False , '1 is True # False', но' (1 == 1) - True # True' или '(1 == 'a') - False # True',' (1 == 'a') is (3 = = 1) # True'. –

+2

@RPGillespie, в каком контексте вы сравниваете число с True/False? Возможно, у вас есть основная логическая ошибка, которую лучше было бы исправить. –

5

равным компаратор Python является строгим при сравнении с 1 по Правда, и от 0 до Ложные за исключением, и это не если значение для 1 или 0 имеет тип float, decimal.Decimal или long. Ноль любого числового типа, например, 0, 0L, 0.0, 0j всегда False. (Обратите внимание, что все остальное, отличное от bool, равно True. См. Truth Value Testing in Python.) 1 любого типа, кроме сложного (1L, 1.0, 1), всегда является True.

В Python:

0 == '0' # False 
0 == '0' and type(0) == type('0') # False, compare short circuits 
0 == '' # False 
0 == '' and type(0) == type('') # False, compare short circuits 

1 == True and type(1) == type(True) # False, makes a difference here 
1 == True # True, also true if 1 was 1.00, etc.. 
0 == False # True 
False == None # False 
0 == bool(None) # True 

Когда первое сравнение возвращает False, то второй не вычисляется, поэтому она короткое замыкание, так как 0 и все остальное 0. Это не нужно, хотя, это будет применяться только к при сравнении с 1 по Правда в строке 6.

в JavaScript:

0 == '0' //true 
0 === '0' //false 
0 == '' //true 
0 === '0' //false 

1 === true //false 
1 == true //true 
0 == false //true 
false == null //false 
0 == !!(null) //true 

Так что ближе всего к JavaScript === в Питоне:

a == b and type(a) == type(b) 

Но нужно использовать только в случае логического сравнения с 1 или 0, что маловероятно. Если вы ожидаете, что значение будет либо числовым, либо логическим, вы можете исправить свой код. Новобранец ошибка состоит в том, чтобы иметь что-то подобное происходит:

a = 0.0 # a valid value, lets assume it comes from a source that can also return None and we have no control over that. 

# Should be: 
# if a not None: 
if a: # a is cast to bool, bool(0.0) is False 
    print "do something here..." 

Просто чтобы прояснить некоторую путаницу, его хорошо, чтобы быть в курсе языка Python является оператором. Python имеет - оператор, который возвращает True, если обе стороны - это, привязаны к одному и тому же объекту, иначе он возвращает False. При использовании строковых литералов время жизни объектов относится только к экземпляру инструкции.Таким образом, выполнение равно на строковых литералах, так как если они одинаковые, они назначаются одному и тому же объекту. Это также относится и к другим неизменным типам, таким как BOOL, и всем типам номера:

0 is '0' # False 
0 is False # False 
0 is 0 # True 

Это не гарантирует работу при сравнении два переменных или переменных и буквальных.

При создании двух пустых списков вы получите два разных объекта, так что есть возвращает значение False:

x = [] 
y = [] 
x is y # False 

Но в данном случае эти переменные ссылаются на тот же список, и будет продолжать делать это, пока они не повторно -assigned или глубокая копия сделана из одного из другого:

x = y = [] 
x is y # True 
x.append(1) 
x is y # True 
x = [1, ] 
x is y # False, even though the value is same 

является оператор сравнения тождества объектов, она выполняет следующие действия:

id('0') == id(0) 

Так что если оба объекта ссылаются на одну и ту же память, они ссылаются на один и тот же объект и поэтому должны быть одинаковыми.

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

Как утверждается в ответе Саймона, философия Питона о равенстве отличается от JavaScript, и на самом деле нет необходимости в строгом компараторе равенства. Компаратор равенства Python не потерян, как JavaScripts ==, но в то же время его не совсем то же самое, что и ===.

Вы должны быть в порядке с компаратором равенства Python до тех пор, пока его ясно, что нуль любого числового типа (0, 0L, 0.0, 0j) всегда равен False и 1 любого числового типа, кроме комплексных чисел (1 , 1L, 1.0) является True.

+0

'==' является строгим только для встроенных объектов - на пользовательских классах он может быть определен как нестрогий, как пожелает дизайнер, поскольку вам может не потребоваться строгое сравнение - это зависит от семантики, которую вы хотите, чтобы ваши классы имели. Также - если вы сравниваете экземпляры объектов - не лучше ли использовать 'is', а не сравнивать' id '. –

1

Вы также можете использовать модуль оператора, если хотите быть строгим. https://docs.python.org/2/library/operator.html

>>> import operator 
>>> operator.eq(True, 1) 
True 
>>> operator.is_(True, 1) 
False 

Некоторые из ответов здесь не правы. Например, Python не будет различать некоторые типы для целей некоторых сравнений.

Например:

>>> 1 == 1.0 
True 
>>> operator.eq(1, 1.0) 
True 
>>> operator.is_(1, 1.0) 
False 

Is работает лучше, чем эк (или ==), но это зависит от переменных бытийных указателей на ту же величину, что означает, что есть много случаев, вы не хотели бы ,

Если вы хотите углубляться, реализуя это коротко, что-то вроде этого: http://code.activestate.com/recipes/384122/ позволит вам «вроде» построить своих собственных операторов.

Смежные вопросы