Могут ли (s это "") и (s == "") когда-либо давать разные результаты в Python 2.6.2? - PullRequest
5 голосов
/ 02 июля 2010

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

Ответы [ 7 ]

12 голосов
/ 02 июля 2010

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

>>> s=u""
>>> print s is ""
False
>>> print s==""
True
11 голосов
/ 02 июля 2010

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

7 голосов
/ 02 июля 2010

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

3 голосов
/ 02 июля 2010

Кажется, это работает для всего, что на самом деле строка, но что-то, что просто выглядит как строка (например, Unicode или подкласс str или что-то подобное), потерпит неудачу.

>>> 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 имеет правильное значение

1 голос
/ 02 июля 2010

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

0 голосов
/ 02 июля 2010

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

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

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

0 голосов
/ 02 июля 2010

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

...