UPDATE:
Идея создания встроенных строк non-iterable была предложенная на python.org в 2006 году. Мой вопрос отличается тем, что я пытаюсь только подавлять эти функции время от времени; все же весь этот поток весьма уместен.
Вот критические комментарии Guido, которые внедрили non-iterable str
на пробной основе:
[...] Я реализовал это (было действительно просто do), но затем я обнаружил, что мне пришлось исправить тонны мест, которые повторяются строки. Например:
sre parser и compiler используют такие вещи, как set ( "0123456789" ), а также перебирают символы входного regexp для его синтаксического анализа.
difflib имеет API, определенный для двух списков строк (типичный поэтапный разброс файла) или двух строк (типичный внутрилинейный diff) или даже два списка (для обобщенного последовательность diff).
небольшие изменения в optparse.py, textwrap.py, string.py.
И я даже не в том месте, где структура regrtest.py даже работает (из-за проблемы с difflib).
Я отказываюсь от этого проекта; патч SF patch 1471291. Я не дольше в пользу этой идеи; это просто не практично, а помещение что есть несколько веских причин для итерации по строке, было опровергнуты случаями использования, которые я нашел как в sre, так и в difflib.
ОРИГИНАЛЬНЫЙ ВОПРОС:
В то время как он является опрятной особенностью языка, что строка является итерируемой, в сочетании с утиным набором текста, это может привести к катастрофе:
# record has to support [] operation to set/retrieve values
# fields has to be an iterable that contains the fields to be set
def set_fields(record, fields, value):
for f in fields:
record[f] = value
set_fields(weapon1, ('Name', 'ShortName'), 'Dagger')
set_fields(weapon2, ('Name',), 'Katana')
set_fields(weapon3, 'Name', 'Wand') # I was tired and forgot to put parentheses
Никакое исключение не будет поднято, и нет простого способа поймать его, кроме как путем тестирования для isinstance(fields, str)
в бесчисленных местах. В некоторых случаях эта ошибка займет очень много времени.
Я хочу отключить строки, которые будут обрабатываться как итерируемые целиком в моем проекте. Это хорошая идея? Можно ли это сделать легко и безопасно?
Возможно, я мог бы подкласса встроенного str
, так что мне нужно было бы явно вызвать get_iter()
, если бы я хотел, чтобы его объект рассматривался как итерабельность. Тогда, когда мне нужен строковый литерал, я бы вместо этого создал объект этого класса.
Вот некоторые касательные вопросы:
Как определить, является ли переменная python строкой или списком?