Похоже, есть два разных способа преобразования строки в байты, как видно из ответов на TypeError: 'str' не поддерживает интерфейс буфера
Какой из этих методов будет лучше или больше Pythonic? Или это просто вопрос личных предпочтений?
b = bytes(mystring, 'utf-8')
b = mystring.encode('utf-8')
python
string
character-encoding
python-3.x
Марк Рэнсом
источник
источник
bytes(item, "utf8")
, поскольку явное лучше, чем неявное, так что ... поstr.encode( )
умолчанию устанавливается в байтах, что делает вас более Unicode-Zen, но менее Explicit-Zen. Также «общий» - это не термин, которому я хотел бы следовать. Кроме того,bytes(item, "utf8")
больше похоже наstr()
, иb"string"
обозначения. Мои извинения, если я так нуб, чтобы понять ваши причины. Спасибо.encode()
он не звонитbytes()
, а наоборот. Конечно, это не сразу очевидно, поэтому я и задал вопрос.Ответы:
Если вы посмотрите на документы для
bytes
, он указывает наbytearray
:Так
bytes
можно сделать гораздо больше, чем просто кодировать строку. Это Pythonic, что позволит вам вызывать конструктор с любым типом исходного параметра, который имеет смысл.Для кодирования строки, я думаю, что
some_string.encode(encoding)
это более Pythonic, чем использование конструктора, потому что это наиболее самодокументируемый - «взять эту строку и кодировать ее с помощью этой кодировки» яснее, чемbytes(some_string, encoding)
- нет явного глагола, когда вы используете конструктор.Изменить: я проверил источник Python. Если вы передаете строку юникода в
bytes
CPython, он вызывает PyUnicode_AsEncodedString , которая является реализациейencode
; так что вы просто пропускаете уровень косвенности, если вы звонитеencode
себя.Кроме того, см. Комментарий Serdalis -
unicode_string.encode(encoding)
также более Pythonic, потому что его инверсия естьbyte_string.decode(encoding)
и симметрия хороша.источник
unicode_string.encode(encoding)
хорошо сочетается с тем,bytearray.decode(encoding)
когда вы хотите вернуть вашу строку.bytearray
используется, когда вам нужен изменяемый объект. Вам не нужно это для простыхstr
↔bytes
преобразований.bytearray
за исключением того, что документы дляbytes
не дают деталей, они просто говорят, что «это неизменная версияbytearray
», поэтому я должен процитировать оттуда.bytes
: Избегайте использование типа байт в виде функции с целочисленным аргументом. В v2 это возвращает целое число, преобразованное в (байтовую) строку, потому что байты являются псевдонимом для str, в то время как в v3 это возвращает строку байтов, содержащую данное число нулевых символов. Так, например, вместо байтов выражения v3 (6) используйте эквивалентный b '\ x00' * 6, который одинаково работает одинаково в каждой версии.byte_string.decode('latin-1')
asutf-8
, не охватывающее весь диапазон от 0x00 до 0xFF (0-255), ознакомьтесь с документацией по Python для: больше информации.Это проще, чем кажется
источник
obj.method()
синтаксис вместоcls.method(obj)
синтаксиса, т.е. использоватьbytestring = unicode_text.encode(encoding)
иunicode_text = bytestring.decode(encoding)
.self
качестве первого аргументаencode
связанный метод в строке. Этот ответ предполагает, что вы должны вместо этого вызвать несвязанный метод и передать ему строку. Это единственная новая информация в ответе, и это неправильно.Абсолютно лучший способ не является ни в 2, но третий. Первый параметр по умолчанию со времен Python 3.0. Таким образом, лучший способ
encode
'utf-8'
Это также будет быстрее, потому что аргумент по умолчанию приводит не к строке
"utf-8"
в коде C, а к томуNULL
, что проверять намного быстрее!Вот некоторые моменты времени:
Несмотря на предупреждение, времена были очень стабильными после повторных прогонов - отклонение составляло всего ~ 2%.
Использование
encode()
без аргумента несовместимо с Python 2, так как в Python 2 кодировка символов по умолчанию - ASCII .источник
'\u00012345'*10000
. Оба берут 28.8us на моем ноутбуке; дополнительные 50 нс, вероятно, теряются при ошибке округления. Конечно, это довольно экстремальный пример, но'abc'
такой же экстремальный в противоположном направлении.