Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python “与”之间有区别吗==&引用;及;“是”吗;?_Python_Reference_Equality_Semantics - Fatal编程技术网

Python “与”之间有区别吗==&引用;及;“是”吗;?

Python “与”之间有区别吗==&引用;及;“是”吗;?,python,reference,equality,semantics,Python,Reference,Equality,Semantics,我的工作让我失望 在Python中,以下两个相等测试是否等效 n = 5 # Test one. if n == 5: print 'Yay!' # Test two. if n is 5: print 'Yay!' 对于要比较实例的对象(如列表)来说,这是否成立 好的,这样回答了我的问题: L = [] L.append(1) if L == [1]: print 'Yay!' # Holds true, but... if L is [1]: print

我的工作让我失望

在Python中,以下两个相等测试是否等效

n = 5
# Test one.
if n == 5:
    print 'Yay!'

# Test two.
if n is 5:
    print 'Yay!'
对于要比较实例的对象(如
列表)来说,这是否成立

好的,这样回答了我的问题:

L = []
L.append(1)
if L == [1]:
    print 'Yay!'
# Holds true, but...

if L is [1]:
    print 'Yay!'
# Doesn't.

因此,
=
测试
所在位置的值
测试它们是否是相同的对象?

=
确定值是否相等,而
is
确定它们是否是完全相同的对象。

is
测试身份
=
平等性测试


每个(小)整数值都映射到单个值,因此每3个值都相同且相等。这是一个实现细节,不是语言规范的一部分,尽管如果两个变量指向同一个对象,
将返回
True
,如果变量引用的对象相等,
=

>>> a = [1, 2, 3]
>>> b = a
>>> b is a 
True
>>> b == a
True

# Make a new copy of list `a` via the slice operator, 
# and assign it to variable `b`
>>> b = a[:] 
>>> b is a
False
>>> b == a
True
在您的例子中,第二个测试只起作用,因为Python缓存小整数对象,这是一个实现细节。对于较大的整数,这不起作用:

>>> 1000 is 10**3
False
>>> 1000 == 10**3
True
字符串文字也是如此:

>>> "a" is "a"
True
>>> "aa" is "a" * 2
True
>>> x = "a"
>>> "aa" is x * 2
False
>>> "aa" is intern(x*2)
True

请同时查看。

您的答案是正确的。
is
操作符比较两个对象的标识。
=
操作符比较两个对象的值

对象的标识在创建后不会改变;您可以将其视为对象在内存中的地址

您可以通过定义
\uuu cmp\uuu
方法或类似
\uuuu eq\uuuu

的方法来控制对象值的比较行为。它们完全不同
is检查对象标识,而
=
检查相等性(这一概念取决于两个操作数的类型)

这只是一个幸运的巧合,“
is
”似乎可以正确处理小整数(例如5==4+1)。那是因为。这种行为完全依赖于实现,不能保证在所有形式的小型转换操作下都能保持

例如,Python 3.5也将短字符串设置为单例,但对它们进行切片会破坏此行为:

>>> "foo" + "bar" == "foobar"
True
>>> "foo" + "bar" is "foobar"
True
>>> "foo"[:] + "bar" == "foobar"
True
>>> "foo"[:] + "bar" is "foobar"
False

看看堆栈溢出问题


它主要归结为“
is
”检查它们是否是相同的对象,而不仅仅是彼此相等(256以下的数字是特例)。

有一个简单的经验法则告诉您何时使用
=
is

  • =
    表示值相等。当您想知道两个对象是否具有相同的值时,请使用它
  • 用于参考等式。如果您想知道两个引用是否引用同一个对象,请使用它
通常,当您将某个内容与简单类型进行比较时,通常会检查值是否相等,因此应该使用
==
。例如,您的示例的目的可能是检查x的值是否等于2(
=
),而不是
x
是否字面上指的是与2相同的对象


还要注意的是:由于CPython引用实现的工作方式,如果您错误地使用
is
来比较整数上的引用相等性,您将得到意外和不一致的结果:

>>> a = 500
>>> b = 500
>>> a == b
True
>>> a is b
False
这正是我们所期望的:
a
b
具有相同的值,但是不同的实体。但是这个呢

>>> c = 200
>>> d = 200
>>> c == d
True
>>> c is d
True
这与先前的结果不一致。这是怎么回事?由于性能原因,Python的参考实现将-5..256范围内的整数对象缓存为单例实例。下面是一个例子来说明这一点:

>>> for i in range(250, 260): a = i; print "%i: %s" % (i, a is int(str(i)));
... 
250: True
251: True
252: True
253: True
254: True
255: True
256: True
257: False
258: False
259: False

这是不使用
is
的另一个明显原因:当您错误地将其用于值相等时,行为将由实现决定。

正如John Feminella所说,大多数情况下,您将使用==和!=因为你的目标是比较价值观。我只想把你剩下的时间会做的事情分类:

NoneType只有一个实例,即None是单例。因此,
foo==None
foo是None
意味着相同。然而,
is
测试速度更快,Pythonic惯例是使用
fooisnone

如果你在做一些内省,或者在垃圾收集方面胡闹,或者检查你定制的string interning小工具是否正常工作,那么你可能有一个
foo
is
bar
的用例

True和False(现在)也是单例,但是没有
foo==True的用例,也没有
foo为True的用例

Python中的
==
Is
之间有区别吗? 是的,它们有一个非常重要的区别

>>> a = b = [1,2,3]
>>> c = [1,2,3]
>>> a == b
True
>>> a == c
True
>>> a is b
True
>>> a is c
False
>>> a = [1,2,3]
>>> b = [1,2]
>>> a == b
False
>>> a is b
False
>>> del a[2]
>>> a == b
True
>>> a is b
False
=
:检查相等性-语义是等价对象(不一定是同一对象)将测试为相等。作为:

运算符,==,>=,
=
之间的区别是什么?
=
是不同的比较!正如其他人已经说过的那样:

  • =
    比较对象的值
  • is
    比较对象的引用
在Python中,名称指对象,例如在本例中,
value1
value2
指存储值
1000
int
实例:

value1 = 1000
value2 = value1

因为
value2
引用了相同的对象
is
=
将给出
True

>>> value1 == value2
True
>>> value1 is value2
True
在以下示例中,名称
value1
value2
引用不同的
int
实例,即使两者存储相同的整数:

>>> value1 = 1000
>>> value2 = 1000

因为存储了相同的值(整数)
==
为True
,这就是原因
>>> [nan] == [nan]
True
>>> (nan,) == (nan,)
True
value1 = 1000
value2 = value1
>>> value1 == value2
True
>>> value1 is value2
True
>>> value1 = 1000
>>> value2 = 1000
>>> value1 == value2
True
>>> value1 is value2
False
class MyClass(object):
    def __init__(self, val):
        self._value = val

    def __eq__(self, other):
        print('__eq__ method called')
        try:
            return self._value == other._value
        except AttributeError:
            raise TypeError('Cannot compare {0} to objects of type {1}'
                            .format(type(self), type(other)))
>>> MyClass(10) == MyClass(10)
__eq__ method called
True
class AClass(object):
    def __init__(self, value):
        self._value = value

>>> a = AClass(10)
>>> b = AClass(10)
>>> a == b
False
>>> a == a
>>> import numpy as np
>>> np.arange(10) == 2
array([False, False,  True, False, False, False, False, False, False, False], dtype=bool)
Yes:   if greeting:
No:    if greeting == True:
Worse: if greeting is True:
str = 'hello'
if (str is 'hello'):
    print ('str is hello')
if (str == 'hello'):
    print ('str == hello')
str is hello
str == hello
str2 = 'hello sam'
    if (str2 is 'hello sam'):
        print ('str2 is hello sam')
    if (str2 == 'hello sam'):
        print ('str2 == hello sam')
str2 == hello sam
str = 'hello'
id('hello')
> 140039832615152
id(str)
> 140039832615152
str2 = 'hello sam'
id('hello sam')
> 140039832615536
id(str2)
> 140039832615792
list1 = [1,2,3,4]
tuple1 = (1,2,3,4)

print(list1)
print(tuple1)
print(id(list1))
print(id(tuple1))

print(list1 == tuple1)
print(list1 is tuple1)
a=[1,2,3]
b=a        #a and b point to the same object
c=list(a)  #c points to different object 

if a==b:
    print('#')   #output:#
if a is b:
    print('##')  #output:## 
if a==c:
    print('###') #output:## 
if a is c:
    print('####') #no output as c and a point to different object 
>>> a = b = [1,2,3]
>>> c = [1,2,3]
>>> a == b
True
>>> a == c
True
>>> a is b
True
>>> a is c
False
>>> a = [1,2,3]
>>> b = [1,2]
>>> a == b
False
>>> a is b
False
>>> del a[2]
>>> a == b
True
>>> a is b
False
Tip: Avoid using is operator for immutable types such as strings and numbers, the result is unpredictable.