Как любой 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
Однако этот вопрос предполагает, что существуют случаи где ( s is "" )
и ( s == "" )
может отличаться. Кто-либо может дать мне пример?
Как уже говорили все, не полагайтесь на неопределенное поведение. Однако, поскольку вы запросили конкретный контрпример для 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.
Кажется, работает для чего угодно который на самом деле является строкой, но что-то, что просто выглядит как строка (например, юникод или подкласс str или что-то подобное), завершится ошибкой.
>>> class mysub(str):
def __init__(self, *args, **kwargs):
super(mysub, self).__init__(*args, **kwargs)
>>>
>>> q = mysub("")
>>> q is ""
False
>>> q == ""
True
edit :
Для целей обзора кода и обратной связи я бы предположил, что это было плохой практикой, потому что он реализует неожиданный тест (даже если мы игнорируем неопределенность в отношении того, будет ли он всегда вести себя одинаково, когда типы совпадают).
if x is ""
Подразумевается, что x имеет правильное значение и тип , но без явной проверки типа, которая предупредила бы будущих сопровождающих или пользователей API и т. Д.
if x == ""
Подразумевает, что x имеет правильное значение
Тебе все равно. В отличие от None
, который определен как одноэлементный, нет правила, которое говорит, что существует только один пустой строковый объект. Таким образом, результатом будет ""
зависит от реализации, а использование равно
- это НЕТ-НЕТ, можете ли вы найти пример или нет.
Вы не можете найти пример, потому что некоторые вещи уникальны и не могут отключаться - поэтому Python хранит их ровно один раз, и поэтому
работает. К ним относятся (), '', u '', True, False, None
CPython даже сохраняет несколько часто используемых чисел, например 0, 0.0, 1, 1.0,
Python is
проверяет идентичность объектов, а не равенство. Вот пример, где использование равно
, а ==
дает другой результат:
>>> s=u""
>>> print s is ""
False
>>> print s==""
True
Скорее всего, нет, CPython во всех случаях оптимизирует ложные экземпляры ""
. Но, как говорят другие, не надейтесь на это.
Неопределенное поведение - непонятная проблема. Есть вещи, которые определены в спецификации Python и которым должны соответствовать придерживающиеся реализации, и есть вещи, оставленные на выбор. Вы можете убедиться, просмотрев исходный код Python, что такое поведение никогда не может произойти для реальных строковых объектов (в отличие от unicode и non-unicode и других показанных близких, но не относящихся к делу примеров). Счастливы, вы оставите такой тест в коде.
Но реализация Python не гарантирует, что она всегда будет работать. Некоторые будущие реализации могут привести к его изменению, и у вас возникнет болезненная несовместимость.
Итак, практическое правило здесь простое: не делайте этого . Используйте операторы только по их прямому и хорошо документированному назначению. Не полагайтесь на артефакты реализации, которые вполне могут измениться в будущем.