del Python

Содержание
Введение
Переменные
Атрибуты
Списки
Словари
Похожие статьи

Введение

В этой статье вы узнаете как работать с оператором удаления del в Python 3.

Важно понять, что del - это именно оператор (инструкция, ключевое слово) а не функция или метод .

Следующий важный факт, о котором нужно помнить - del не вызывает __del__(). Примеры разобраны в конце статьи .

Официальная документация

Переменные

С помощью del можно удалять переменные.

a = 3 print(id(a)) del a print(id(a))

140727511501304 Traceback (most recent call last): File "C:\A\demo_del.py", line 5, in <module> print(id(a)) ^ NameError: name 'a' is not defined

Можно удалить сразу несколько переменных.

a = 1 b = 2 c = 3 del a, b, c print(b)

NameError: name 'b' is not defined

Атрибуты

С помощью del можно удалять атрибуты объектов.

class A: pass a = A() a.one = 1 a.two = 2 print(a.one, a.two) del a.two print(a.one, a.two)

1 2 Traceback (most recent call last): File "C:\A\demo_del.py", line 11, in <module> print(a.one, a.two) ^^^^^ AttributeError: 'A' object has no attribute 'two'

Для полноты картины напоминаю, что безопасный способ получить атрибут если он есть - это применение getattr()

print(getattr(a, "one", None)) print(getattr(a, "two", None))

1 None

Или hasattr()

if hasattr(a, "two"): print(a.two) else: print(None)

None

С помощью __delattr__() можно задать поведение при удалении атрибута.

class A: def __delattr__(self, name): print(f"Deleting attribute {name}") super().__delattr__(name) a = A() a.x = 10 print(a.x) del a.x print(a.x)

10 Deleting attribute x Traceback (most recent call last): File "C:\A\demo_del.py", line 11, in <module> print(a.x) ^^^ AttributeError: 'A' object has no attribute 'x'

Списки

С помощью del можно удалять элементы из списков .

c = ['Armenia', 'Finland', 'Georgia', 'Germany', 'Italy', 'Russia', 'Spain', 'Sweden'] del c[3] print(c)

['Armenia', 'Finland', 'Georgia', 'Italy', 'Russia', 'Spain', 'Sweden']

Чтобы удалять по содержимому а не индексу - можно применить index()

c = ['Armenia', 'Finland', 'Georgia', 'Italy', 'Russia', 'Spain', 'Sweden'] del c[c.index('Sweden')] print(c)

['Armenia', 'Finland', 'Georgia', 'Italy', 'Russia', 'Spain']

Из списка можно удалять отрезки.

lst = [1, 2, 3, 4, 5] del lst[1:4] print(lst) # [1, 5]

[1, 5]

Словари

С помощью del можно удалять элементы из словарей по ключу.

del obj[key]

Равносильно вызову

obj.__delitem__(key)

d = {"PHP": 1995, "Java": 1995, "C": "1972"} print(d) del d["PHP"] print(d)

{'PHP': 1995, 'Java': 1995, 'C': '1972'} {'Java': 1995, 'C': '1972'}

С помощью __delitem__() можно задать поведение при удалении элемента.

class B: def __delitem__(self, key): print(f"Deleting item {key}") b = B() del b["my_item"]

Deleting item my_item

В настоящем словаре удаление элемента происходит бесшумно. Класс В в примере выше содержит только удаление. Чтобы сделать подобие словаря нужно задать и другие методы.

class LoggedDict: def __init__(self): print(f"Init LoggedDict") self.data = {} def __setitem__(self, key, value): print(f"Setting value {value} for key {key}") self.data[key] = value def __getitem__(self, key): print(f"Getting value for key {key}") return self.data[key] def __delitem__(self, key): print(f"Deleting key {key}") del self.data[key] d = LoggedDict() d["x"] = 10 print(d["x"]) del d["x"] print(d["x"])

Init LoggedDict Setting value 10 for key x Getting value for key x 10 Deleting key x Getting value for key x Traceback (most recent call last): File "C:\A\demo_del.py", line 24, in <module> print(d["x"]) ~^^^^^ File "C:\A\demo_del.py", line 11, in __getitem__ return self.data[key] ~~~~~~~~~^^^^^ KeyError: 'x'

Модули

С помощью del можно удалять элементы из импортируемыех модулей или классов.

import math print(math.e) print(math.pi) del math.pi print(math.e) print(math.pi)

2.718281828459045 3.141592653589793 2.718281828459045 Traceback (most recent call last): File "C:\A\demo_del.py", line 10, in <module> print(math.pi) ^^^^^^^ AttributeError: module 'math' has no attribute 'pi'

del не равно __del__()

del не вызывает __del__().

Мы уже видели примеры где del вызвает __delattr__() и __delitem__() в зависимости от типа объекта. Чего del не делает - так это не вызывает __del__() напрямую.

del удаляет ссылку на имя. И если это единственнная ссылка - __del__() действительно будет вызван.

class A: def __del__(self): print("A is being destroyed") a = A() del a input("Type something")

A is being destroyed Type something

Сначала появилось сообщение об уничтожении объекта A is being destroyed и только потом Type something.

То есть объект был уничтожен в скрипт, а не во время закрытия скрипта.

Это не должно вводить в заблужение, так как если есть и другие ссылки, удаление одной не приведёт к уничтожению объекта.

Создадим ещё одну ссылку.

class A: def __del__(self): print("A is being destroyed") a = A() b = a del a input("Type something")

Type something A is being destroyed

Теперь первым появляется сообщение Type something.

Значит скрипт дошёл до самого конца а объект так и не был уничтожен. del a не привело к вызову __del__() потому что сущестовала ссылка от b.

Объект был уничтожен только во время закрытия скрипта.

Автор статьи: Андрей Олегович

Похожие статьи
Основы Python
Type Hints
__future__
configparser
Менеджер контекста
docstring
#!: Shebang
Объекты
Итерация
os
pathlib
flake8

Поиск по сайту

Подпишитесь на Telegram канал @aofeed чтобы следить за выходом новых статей и обновлением старых

Перейти на канал

@aofeed

Задать вопрос в Телеграм-группе

@aofeedchat

Контакты и сотрудничество:
Рекомендую наш хостинг beget.ru
Пишите на info@urn.su если Вы:
1. Хотите написать статью для нашего сайта или перевести статью на свой родной язык.
2. Хотите разместить на сайте рекламу, подходящую по тематике.
3. Реклама на моём сайте имеет максимальный уровень цензуры. Если Вы увидели рекламный блок недопустимый для просмотра детьми школьного возраста, вызывающий шок или вводящий в заблуждение - пожалуйста свяжитесь с нами по электронной почте
4. Нашли на сайте ошибку, неточности, баг и т.д. ... .......
5. Статьи можно расшарить в соцсетях, нажав на иконку сети: