Почему в python нет метода list.clear ()?
Вопрос
Вдохновленный этим вопросом.
Почему в python нет метода list.clear ()? Я нашел здесь несколько вопросов, в которых говорится, что правильный способ сделать это - один из следующих, но никто не сказал, почему для этого нет только одного метода.
del lst[:]
lst[:] = []
Хотя это может идти вразрез с «дзен питона» чтобы иметь более чем один способ сделать что-то, мне, безусловно, кажется более очевидным наличие " list.clear () " метод. Это также соответствовало бы указаниям и наборам, оба из которых имеют .clear ().
Я натолкнулся на несколько сообщений об этих идеях python-dev и python и не нашел однозначного ответа (см. здесь (2006) и здесь (2009)). Взвешивал ли это Гвидо? Это просто спорный вопрос, который еще не решен за последние 4-5 лет?
Обновление: list.clear () был добавлен в python в версии 3.3 - см. здесь р>
Решение
В связанных темах Раймонд Хеттингер в значительной степени подводит итог плюсы и минусы добавления этого метода. Когда дело доходит до языкового дизайна, очень важно быть консервативным. См., Например, " каждая функция начинается с -100 баллов " Принцип команды C # есть. Вы не можете получить что-то такое же чистое, как Python, добавляя новые функции. Просто взгляните на некоторые из более жестких популярных скриптовых языков, чтобы увидеть, куда вас это приведет.
Я полагаю, что метод .clear ()
просто никогда не пересекал неявное правило -100 баллов, чтобы стать чем-то, что стоит добавить в основной язык. Несмотря на то, что имя метода уже используется для эквивалентной цели и найти альтернативу может быть сложно, вероятно, это не так уж и далеко.
Другие советы
В то время как на этот вопрос не было list.clear ()
, у 3.3 теперь есть один (как было запрошено в http://bugs.python.org/issue10516 ). Кроме того, методы clear ()
были добавлены в bytearray
и MutableSequence
для облегчения переключения между списками и другими коллекциями (set, dict и т. Д.).
Подробную информацию об изменении можно найти здесь . р>
Я не могу ответить на почему; но он обязательно должен быть один, поэтому разные типы объектов могут быть очищены с помощью одного и того же интерфейса.
Очевидный простой пример:
def process_and_clear_requests(reqs):
for r in reqs:
do_req(r)
reqs.clear()
Для этого требуется, чтобы объект поддерживал итерацию и чтобы он поддерживал clear (). Если бы у списков был метод clear (), он мог бы принять список или установить его одинаково. Вместо этого, поскольку наборы и списки имеют разные API для удаления их содержимого, это не работает; в итоге вы получите излишне уродливый хак, например:
def process_and_clear_requests(reqs):
for r in reqs:
do_req(r)
if getattr(reqs, "clear"):
reqs.clear()
else:
del reqs[:]
Насколько мне известно, использование del obj [:] или obj [:] = [] - это просто неприятные, не интуитивно понятные способы обойти тот факт, что в списке отсутствует clear ().
Это уменьшает "избыточность" к ошибке, когда это повреждает согласованность языка, что еще более важно.
Что вы должны использовать, я бы порекомендовал del obj [:]. Я думаю, что это проще реализовать для объектов, не похожих на список.
При тестировании часто бывает полезно настроить данные, образующие область тестов, в глобальные переменные, чтобы тесты могли опираться друг на друга, если это необходимо / проще. В таких случаях наличие метода для очистки списка позволит вам сделать это без необходимости объявлять эти переменные как глобальные в функции (то есть в тестах). Я знаю, что тесты не должны зависеть друг от друга ...
Вопрос должен заключаться в том, почему clear
было сочтено необходимым в первую очередь. Следующее работает, чтобы очистить любую коллекцию Python, о которой я могу думать.
def clear(x):
return type(x)()
>>> s = {1, 2, 3}
>>> s
set([1, 2, 3])
>>> s = clear(s)
>>> s
set([])
>>> l = [1, 2, 3]
>>> l
[1, 2, 3]
>>> l = clear(l)
>>> l
[]