Может (s быть “”), и (s == “”) когда-нибудь дают различные результаты в Python 2.6.2?

Как любой 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 == "" ) может отличаться. Кто-либо может дать мне пример?

5
задан Community 23 May 2017 в 10:32
поделиться

7 ответов

Как уже говорили все, не полагайтесь на неопределенное поведение. Однако, поскольку вы запросили конкретный контрпример для 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.

11
ответ дан 18 December 2019 в 05:30
поделиться

Кажется, работает для чего угодно который на самом деле является строкой, но что-то, что просто выглядит как строка (например, юникод или подкласс 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 имеет правильное значение

3
ответ дан 18 December 2019 в 05:30
поделиться

Тебе все равно. В отличие от None , который определен как одноэлементный, нет правила, которое говорит, что существует только один пустой строковый объект. Таким образом, результатом будет "" зависит от реализации, а использование равно - это НЕТ-НЕТ, можете ли вы найти пример или нет.

7
ответ дан 18 December 2019 в 05:30
поделиться

Вы не можете найти пример, потому что некоторые вещи уникальны и не могут отключаться - поэтому Python хранит их ровно один раз, и поэтому работает. К ним относятся (), '', u '', True, False, None CPython даже сохраняет несколько часто используемых чисел, например 0, 0.0, 1, 1.0,

1
ответ дан 18 December 2019 в 05:30
поделиться

Python is проверяет идентичность объектов, а не равенство. Вот пример, где использование равно , а == дает другой результат:

>>> s=u""
>>> print s is ""
False
>>> print s==""
True
12
ответ дан 18 December 2019 в 05:30
поделиться

Скорее всего, нет, CPython во всех случаях оптимизирует ложные экземпляры "" . Но, как говорят другие, не надейтесь на это.

0
ответ дан 18 December 2019 в 05:30
поделиться

Неопределенное поведение - непонятная проблема. Есть вещи, которые определены в спецификации Python и которым должны соответствовать придерживающиеся реализации, и есть вещи, оставленные на выбор. Вы можете убедиться, просмотрев исходный код Python, что такое поведение никогда не может произойти для реальных строковых объектов (в отличие от unicode и non-unicode и других показанных близких, но не относящихся к делу примеров). Счастливы, вы оставите такой тест в коде.

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

Итак, практическое правило здесь простое: не делайте этого . Используйте операторы только по их прямому и хорошо документированному назначению. Не полагайтесь на артефакты реализации, которые вполне могут измениться в будущем.

0
ответ дан 18 December 2019 в 05:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: