odnochlen
А где тут очистка, если в действительности происходит усложнение: в юникоде элемент имеет тот же тип, что он сам и срез, а в байтах - нет?
Гм, а где вы видели именно байты в двойке? Там было:
object
| \
int \
basestring
| \
str(8bit) unicode(code points)
В тройке что-то вроде
object
/ | \
| | \________
int | \
| \
str(code points) byte
А срез это вообще (по моему
) очень удачная замена для substr/copyOfRange/array_slice и.т.д (да еще и в синтаксе).
Т.е не надо в зависимости от типа писать foo.substr/foo.copy(1,2,3). Вполне логично, что срез всегда возвращает тотже тип - если не путать срез ( x : y : z ) с доступом к
одному определенному элементу foo(x)
.
То что в str/unicode элементы тогоже типа - просто language design decision. Можно конечно спорить, но единственная альтернатива - ввести дополнительный тип (char) и продумать, что должен выдавать к примеру ‘x’ + ‘abc’, ‘x’ + ‘y’, foo.find('abc'), foo.find('a').
И кому от этого легче станет (благо пришлось бы и тут выбирать что-то одно - эрго были бы недовольные
) ?
Или наоборот: пусть элемент в byte будет тоже списком:
Во первых: тогда вообще list(x) должен возвращать список - что бы все было унитарно (хотя так и до dict(x) дойти можно).
Во вторых: как добратся до конкретного байта? Вызывать что-то вроде byt_to_int(mybytes(x))?
И что тогда можно передать byte_to_int - только список с одним элементом? Если нет: то что использовать по умолчанию при преобразовании - BigEndian или LittleEndian?
И.т.д.
Тоесть: при работе c строками по моему не особо важно, состоит ли строка из отдельных символов или из строк с единичной длиной. И если можно не плодить сущности - почему бы и нет
При работе с списком обычно через индекс нужен доступ к определенному элементу (благо если действительно нужен “sublist/subarray” - можно использовать срезы).