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 |