正如任何Python程序员所知,您应该使用==
而不是is
来比较两个字符串的相等性。但是,实际上是否存在( s is "" )
和( s == "" )
在Python 2.6.2中会产生不同结果的任何情况?
我最近遇到过在代码审查中使用( s is "" )
的代码,虽然指出这是不正确的,但我想举例说明这可能会失败。但是尽可能地尝试,我不能构造两个具有不同身份的空字符串。似乎Python实现必须在许多常见操作中特殊情况下使用空字符串。例如:
>>> a = ""
>>> b = "abc"[ 2:2 ]
>>> c = ''.join( [] )
>>> d = re.match( '()', 'abc' ).group( 1 )
>>> e = a + b + c + d
>>> a is b is c is d is e
True
但是,this question表明是 ( s is "" )
和( s == "" )
可能不同的情况。谁能举个例子呢?
答案 0 :(得分:12)
Python is
测试对象标识而不是相等。以下是使用is
和==
给出不同结果的示例:
>>> s=u""
>>> print s is ""
False
>>> print s==""
True
答案 1 :(得分:11)
正如其他人所说,不要依赖未定义的行为。但是,由于您要求Python 2.6的特定反例,这里是:
>>> s = u"\xff".encode('ascii', 'ignore')
>>> s
''
>>> id(s)
10667744
>>> id("")
10666064
>>> s == ""
True
>>> s is ""
False
>>> type(s) is type("")
True
Python 2.6唯一能够以空字符串形式结束的时间是不正常的空字符串,这是因为它执行字符串操作并且事先不确定该字符串的长度。因此,当您对字符串进行编码时,错误处理程序最终可以剥离字符并在完成后修复缓冲区大小。当然这是一个疏忽,可以在Python 2.7中轻松改变。
答案 2 :(得分:7)
你不应该在乎。与被定义为单例的None
不同,没有规则表明只有一个空字符串对象。所以s is ""
的结果是依赖于实现的,使用is
是NO-NO,无论你是否能找到一个例子。
答案 3 :(得分:3)
它似乎适用于任何实际上字符串,但看起来像字符串的东西(例如str的unicode或子类或类似的东西)将失败。
>>> class mysub(str):
def __init__(self, *args, **kwargs):
super(mysub, self).__init__(*args, **kwargs)
>>>
>>> q = mysub("")
>>> q is ""
False
>>> q == ""
True
修改:
用于代码审查和&反馈我建议这是不好的做法,因为它实现了一个意外的测试(即使我们忽略了当类型匹配时它是否总是表现相同的不确定性。)
if x is ""
意味着x具有正确的值并且键入,但是没有明确的类型测试会警告未来的维护者或api用户等。
if x == ""
意味着x只是正确的值
答案 4 :(得分:1)
你找不到一个例子,因为有些东西是独特的而且不是可静态的 - 所以Python只保留了一次,因此is
可以工作。这些包括(), '',u'', True, False, None
CPython甚至保留了一些常用的数字,即0, 0.0, 1, 1.0,
答案 5 :(得分:0)
可能不会,CPython似乎在所有情况下优化""
的虚假实例。但正如其他人所说,不要依赖于此。
答案 6 :(得分:0)
未定义的行为是一个模糊的问题。 Python规范定义的内容和实现必须符合的内容,还有一些事情可供选择。通过查看Python的源代码,您可能会确信这种行为永远不会发生在实际的字符串对象上(与unicode与非unicode和其他接近但不相关的示例不同)。很高兴,你将在代码中留下这样的测试。
但Python实现并不能保证它始终有效。未来的一些实施可能会导致它发生变化,并且您会遇到痛苦的不兼容性。
因此,经验法则很简单:不要这样做。仅将操作符用于其预期和记录良好的用途。不要依赖可能在未来很好地改变的实现工件。