Проверка идентичности с is, очевидно, не может в обоих случаях.
Но почему они реализуют такое поведение в Python3?
Ответ 1
В Python 2.x целью проектирования для юникода является включение прозрачных операций между строк Unicode и байтов путем неявного преобразования двух типов. Когда вы выполняете сравнение u"" == "", unicode Юникода автоматически кодируется в байтовую строку сначала, а затем сравнивается с str RHS. Вот почему он вернул True.
Напротив, Python 3.x, узнав из беспорядка юникода, который был в Python 2, решил сделать все, что явствует из строк unicode vs. byte. Таким образом, b"" == "" является False потому что строка байта больше не будет автоматически преобразована в unicode для сравнения.
Ответ 2
В питоне 3 строка - это Юникод. Тип, используемый для хранения текста, это str а тип для хранения данных - bytes.
типы str и bytes не могут быть смешаны, вы всегда должны явно конвертировать между ними. Используйте str.encode() для перехода от bytes.decode() к байту и bytes.decode() для перехода от байта к строке.
Поэтому, если вы выполните b"".decode() == "" вы получите True:
Дизайнеры решили не предполагать кодирование для принуждения при сравнении байтов со строками, поэтому оно подпадает под поведение Python 3.x по умолчанию, в результате чего сбрасываются сравнения, содержащие разные типы.