严格比较

时间:2015-01-19 21:34:23

标签: python python-3.x

在javascript中,有严格的比较运算符op1 === op2op1 !== op2将比较类型和值。是否有一种实现相同目标的pythonic方式?

到目前为止,我只能提出以下凌乱的条件:

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

5 个答案:

答案 0 :(得分:9)

您的方法确实会检查值和类型。 Python中没有不同的运算符。

有人说,在很多情况下,这不是你想要的 - 在Python的哲学中,任何表现为鸭子的对象都应该被视为鸭子。你通常不只想要字典,你想要“类似映射”的对象等等 - 只要对象可以用于特定任务,那么代码就应该接受它。

答案 1 :(得分:6)

Python的相等比较器是严格的,除了将1与True,0与False进行比较时,如果1或0的值是float,decimal.Decimal或者类型,则无关紧要。长。任何数字类型的零,例如,0,0L,0.0,0j始终为False。 (注意,任何其他强制转换为bool都是True。请参阅Truth Value Testing in Python。)除了复数(1L,1.0,1)之外的任何类型的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.这是不必要的,但它只适用于在第6行比较1和True时。

在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

因此,Python中与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

但是在这种情况下,这些变量引用相同的列表,并且将继续这样做,直到它们被重新分配,或者深层复制一个来自另一个:

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)

因此,如果两个对象都引用相同的内存,则它们引用相同的对象,因此必须相同。

除非你想检查两个对象是否引用相同的内存,否则最好避免 进行严格的比较。

正如Simon的回答所说,Python关于平等的哲学不同于JavaScript,并且确实不需要严格的相等比较器。 Python的相等比较器不像JavaScripts ==那样松散,但同时它与===不完全相同。

你应该对Python的相等比较器没问题,只要它清楚你任何数字类型的零(0,0L,0.0,0j)总是等于False和任何数字类型的1除了复杂数字(1,1L,1.0)为真。

答案 2 :(得分:2)

Python的相等比较器在很大程度上总是严格的。

例如:

的Python

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

的Javascript

0 == '0'  //True
0 === '0'  //False
0 == ''  //True
0 === '0' //False

答案 3 :(得分: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

效果比eq(或==)更好,但它取决于变量是同一个值的指针,这意味着很多情况下你都不会喜欢。

如果你想深入了解,以速记的方式实现这一点,就像这样:http://code.activestate.com/recipes/384122/会让你"有点"建立自己的运营商。

答案 4 :(得分:0)

在python中,只有一个严格的比较运算符为== 假设我们有2种情况:

>>> 2 == '2'
False

# Comparison of Int with string, it returns False
>>> 2 == 2.0
True

# Comparison of Int with Float, it returns True

但是在Julia等其他编程语言中,比较运算符和严格比较运算符之间是有区别的。

>>> 2 == 2.0
true

>>> 2 === 2.0
false

# strict comparison operator, namely === which is true only if two values agree fully as to type as well as value.