Я не могу придумать причину, по которой python нуждается в del
ключевом слове (и большинство языков, похоже, не имеют аналогичного ключевого слова). Например, вместо того, чтобы удалить переменную, можно просто присвоить None
ей. И при удалении из словаря, del
метод может быть добавлен.
Есть ли какая-то причина, чтобы оставаться del
в Python, или это пережиток дней сбора мусора в Python?
python
dictionary
python-internals
del
Джейсон Бейкер
источник
источник
del
.del
не является следствием предварительной сборки мусора, потому что вы всегда можете это сделатьused = None
. Просто всегда имело смысл иметь определенный синтаксис для него. Поскольку сейчас у нас цилиндрический ГХ, случаи, когда вы хотите использовать любой из них, невелики.ERASE
(убить определенные переменные) иCLEAR
(убить все переменные)Ответы:
Во-первых, вы можете исключить другие вещи, кроме локальных переменных
Оба из которых должны быть явно полезными. Во-вторых, использование
del
локальной переменной делает намерение более понятным. Для сравнения:в
Я знаю, что в случае
del foo
этого цель состоит в том, чтобы удалить переменную из области видимости. Не ясно, чтоfoo = None
делает это. Если кто-то только что назначил,foo = None
я мог бы подумать, что это мертвый код. Но я сразу знаю, чтоdel foo
пытался сделать кто-то, кто кодирует .источник
del
использовалось в вычислениях с интенсивным использованием памяти, но когда я увидел это, я сразу понял, почему это было необходимо.del
для обозначения намерения (поскольку комментарий может сделать то же самое без добавления к языку), но я полагаю, что это лучший ответ.len()
функцию таким же образом. Если это так, вопрос может быть закрыт как мнение или даже на вкус. Python просто имеет тенденцию предоставлять примитивы для основных операций вместо того, чтобы полагаться на методы.Вот что
del
делает (из справочника по языку Python ):Присвоение
None
имени не удаляет привязку имени из пространства имен.(Я предполагаю, что могут быть некоторые дебаты о том, действительно ли удаление привязки имени полезно , но это другой вопрос.)
источник
del
убирает привязку имени, поскольку он предложил назначитьNone
в качестве альтернативы.NameError
. Грег Хьюгилл делает это самое различие. И именно это различие делает ваше утверждение о том, что плакат «ясно» понят мне неясным.Одно место, которое я нашел
del
полезным, - это очистка внешних переменных в циклах for:Теперь вы можете быть уверены, что x будет неопределенным, если вы используете его вне цикла for.
источник
del
строка здесь должна быть с отступом (т.е. частью цикла)?NameError: name 'x' is not defined
если список пуст.Удаление переменной отличается от установки на None
Удаление имен переменных с помощью
del
, вероятно, редко используется, но это невозможно достичь без ключевого слова. Если вы можете создать имя переменной, написавa=1
, приятно, что вы теоретически можете отменить это, удалив a.В некоторых случаях это может облегчить отладку, поскольку попытка доступа к удаленной переменной вызовет NameError.
Вы можете удалить атрибуты экземпляра класса
Python позволяет написать что-то вроде:
Если вы решите динамически добавлять атрибуты в экземпляр класса, вы наверняка захотите отменить его, написав
источник
Есть конкретный пример того, когда вы должны использовать
del
(могут быть и другие, но я знаю об этом один раз), когда вы используетеsys.exc_info()
для проверки исключения. Эта функция возвращает кортеж, тип возникшего исключения, сообщение и трассировку.Первых двух значений обычно достаточно, чтобы диагностировать ошибку и воздействовать на нее, но третье содержит весь стек вызовов между тем, где возникло исключение, и тем, где исключение перехвачено. В частности, если вы делаете что-то вроде
traceback
tb
заканчивается в локальных элементах стека вызовов, создавая циклическую ссылку, которую нельзя собрать мусором. Таким образом, важно сделать:разорвать круговую ссылку. Во многих случаях , когда вы хотели бы назвать
sys.exc_info()
, как с метаклассом магии, отслеживающий это полезно, так что вы должны убедиться , что вы очистить его , прежде чем вы можете возможно оставить обработчик исключений. Если вам не нужна трассировка, вы должны немедленно удалить ее или просто выполните:Чтобы избежать всего этого вместе.
источник
Просто другое мышление.
При отладке приложений http в среде, такой как Django, стек вызовов, полный бесполезных и испорченных ранее переменных, особенно когда это очень длинный список, может быть очень болезненным для разработчиков. Таким образом, на этом этапе управление пространством имен может быть полезным.
источник
Использование «del» явно также лучше, чем присвоение переменной None. Если вы попытаетесь удалить переменную, которая не существует, вы получите ошибку времени выполнения, но если вы попытаетесь установить переменную, которая не существует, None, Python автоматически установит новую переменную в None, оставив переменную, которую вы хотел удалить, где это было. Так что Del поможет вам поймать ваши ошибки раньше
источник
Чтобы добавить несколько пунктов к ответам выше:
del x
Определение
x
указываетr -> o
(ссылка,r
указывающая на объектo
), ноdel x
изменяется,r
а неo
. Это операция над ссылкой (указателем) на объект, а не на объект, связанный с нимx
. Различение междуr
иo
является ключевым здесь.locals()
.globals()
еслиx
принадлежит там.x
принадлежит, а не на то, кудаx
указывает. Единственное физическое изменение в памяти - это. Например, если онx
находится в словаре или списке, он (как ссылка) удаляется оттуда (и не обязательно из пула объектов). В этом примере словарьlocals()
, которому он принадлежит, является стеком frame ( ), который перекрывается сglobals()
.источник
Принудительное закрытие файла после использования numpy.load:
Использование ниши возможно, но я нашел это полезным при использовании
numpy.load
для чтения файла. Время от времени я обновлял файл, и мне нужно было скопировать файл с таким же именем в каталог.Я использовал,
del
чтобы выпустить файл и позволить мне скопировать в новый файл.Примечание. Я хочу избежать
with
диспетчера контекста, поскольку я поиграл с графиками в командной строке и не хотел много нажимать на вкладку!Смотрите этот вопрос.
источник
__del__()
метод для мусорных объектов или даже если он вызывается вообще. Таким образом, API, которые не предлагают никакого способа освобождения ресурсов, кроме как надеются, что__del__()
метод вызывается через некоторое время (вскоре после того, как объект стал мусором), в некоторой степени нарушаются.del
часто встречается в__init__.py
файлах. Любая глобальная переменная, определенная в__init__.py
файле, автоматически «экспортируется» (она будет включена вfrom module import *
). Один из способов избежать этого - определить__all__
, но это может запутаться, и не все используют это.Например, если у вас был код
__init__.py
какТогда ваш модуль будет экспортировать
sys
имя. Вы должны вместо этого написатьисточник
В качестве примера того, что
del
можно использовать, я считаю это полезным в следующих ситуациях:Эти две функции могут быть в разных пакетах / модулях, и программисту не нужно знать, что
c
вf
действительности имеет аргумент значения по умолчанию . Таким образом, используя kwargs в сочетании с del, вы можете сказать «Я хочу значение по умолчанию для c», установив его в None (или в этом случае также оставьте его).Вы можете сделать то же самое с чем-то вроде:
Однако предыдущий пример я считаю более СУХИМ и элегантным.
источник
Вы можете использовать его для удаления одного элемента массива вместо синтаксиса среза
x[i:i+1]=[]
. Это может быть полезно, если, например, вы находитесьos.walk
и хотите удалить элемент в каталоге. Я бы не счел это ключевым словом полезным, поскольку можно было бы просто создать[].remove(index)
метод (на.remove
самом деле это метод search-and-remove-first-instance-of-value).источник
[].pop(index)
и[].remove(item)
. Не используйте переменную named,"index"
когда говорите о значении, это выглядит странно.Я обнаружил,
del
что это полезно для псевдо-ручного управления памятью при обработке больших данных с помощью Numpy. Например:В этом может заключаться разница между остановкой скрипта, когда система переходит в бешенство, когда Python GC не может успевать, и работает идеально плавно, когда порог свободной памяти остается достаточным, чтобы использовать машину для просмотра. и код, пока он работает.
источник
Я думаю, что одна из причин, по которой del имеет свой собственный синтаксис, заключается в том, что в некоторых случаях замена его на функцию может быть сложной, поскольку она работает с привязкой или переменной, а не со значением, на которое она ссылается. Таким образом, если нужно создать версию функции del, необходимо передать контекст. Del foo должен был бы стать globals (). Remove ('foo') или locals (). Remove ('foo'), что приводит к беспорядку и менее читаемый. Тем не менее, я говорю, что избавление от del было бы хорошо, учитывая его, казалось бы, редкое использование. Но удаление языковых особенностей / недостатков может быть болезненным. Может быть, Python 4 удалит это :)
источник
Я хотел бы остановиться на принятом ответе, чтобы подчеркнуть нюанс между установкой переменной
None
и ее удалением с помощьюdel
:Дана переменная
foo = 'bar'
и следующее определение функции:После первоначального объявления
test_var(foo)
доходностьvariable tested true
соответствует ожидаемой.Теперь попробуйте:
который дает
variable tested false
.Сравните это поведение с:
который сейчас поднимает
NameError: name 'foo' is not defined
.источник
Еще одно использование ниши: в pyroot с ROOT5 или ROOT6 «del» может быть полезен для удаления объекта python, который ссылается на более не существующий объект C ++. Это позволяет динамическому поиску Pyroot находить объект C ++ с одинаковым именем и связывать его с именем Python. Таким образом, вы можете иметь такой сценарий:
Надеюсь, эта ниша будет закрыта благодаря более рациональному управлению объектами ROOT7.
источник
Команда "del" очень полезна для управления данными в массиве, например:
Вывод:
['B', 'C', 'D']
источник
Однажды мне пришлось использовать:
потому что используя только:
не освободил последовательный порт достаточно быстро, чтобы немедленно открыть его снова. Из этого урока я узнал, что на
del
самом деле означало: «Собери это СЕЙЧАС! И подожди, пока это будет сделано», и это действительно полезно во многих ситуациях. Конечно, вы можете иметьsystem.gc.del_this_and_wait_balbalbalba(obj)
.источник
__del__()
всегда неправильно в Python (хотя я не знаю причин такого дизайна), и лучше использовать API менеджера контекста (with
утверждение).serial
Модуль также работает с Jython , чтобы ваш хак не работает там!del является эквивалентом «unset» во многих языках и как точка пересечения, переходящая с другого языка на python. Люди склонны искать команды, которые делают то же самое, что они делали на своем родном языке ... также устанавливают переменная в "" или "none" на самом деле не удаляет переменную из области видимости ... она просто очищает ее значение, а имя самой переменной все равно будет храниться в памяти ... почему?!? в скрипте, интенсивно использующем память .. хранение мусора позади его просто нет нет и в любом случае ... у каждого языка есть какая-то форма функции "unset / delete" var .. почему не python?
источник
del
не вызывает сборщик мусора быстрее, чем= None
и не оставит мусор в долгосрочной перспективе. Возможно, вы захотите собрать мусор в Python.Каждый объект в Python имеет идентификатор Type, связанный с ним счетчик ссылок, когда мы используем del, счетчик ссылок уменьшается, когда счетчик ссылок становится равным нулю, это потенциальный кандидат для сбора мусора. Это отличает del по сравнению с установкой идентификатора в None. В более позднем случае это просто означает, что объект просто пропущен (до тех пор, пока мы не выйдем из области видимости, в этом случае счет уменьшится), и теперь просто идентификатор указывает на какой-то другой объект (область памяти).
источник