Python: уроки, справочник и задачи

delattr(): как удалить атрибут объекта в Python

Раздел: Функции Python · Обновлено 31.10.2026

Функция delattr() в Python удаляет атрибут у объекта, если сам объект это разрешает, а имя атрибута передается строкой. Разберем синтаксис, удаление атрибутов экземпляра и класса, разницу между delattr() и оператором del, типичные ошибки и способ запретить удаление через метод __delattr__.

Python delattr
Фото: Alex Morfin / CC BY-SA 3.0, Wikimedia Commons
Содержание статьи
  1. Синтаксис delattr()
  2. Удаление атрибута экземпляра
  3. Удаление атрибута класса
  4. delattr() или del
  5. Ошибки и ограничения
  6. Метод __delattr__ и защита атрибутов
  7. Где delattr() применяется на практике
  8. Частые вопросы
    1. Что возвращает delattr()?
    2. Можно ли удалить метод класса через delattr()?
    3. Можно ли удалить переменную модуля?
    4. Чем delattr() отличается от присваивания None?

Синтаксис delattr()

Функция встроенная, импортировать ее не нужно. Она принимает два обязательных аргумента и ничего не возвращает (результат вызова равен None).

delattr(object, name)

Вызов delattr(obj, 'color') полностью равносилен записи del obj.color. Функция входит в четверку инструментов для работы с атрибутами по имени вместе с getattr(), setattr() и hasattr(). Остальные встроенные функции собраны на странице встроенных методов и функций.

Удаление атрибута экземпляра

Атрибуты, созданные в __init__ через self, хранятся в словаре __dict__ конкретного объекта. delattr() убирает запись из этого словаря, другие экземпляры класса не затрагиваются.

class User:
    def __init__(self, name, token):
        self.name = name
        self.token = token

u1 = User('anna', 'abc123')
u2 = User('boris', 'xyz789')

delattr(u1, 'token')
print(u1.__dict__)            # {'name': 'anna'}
print(hasattr(u1, 'token'))   # False
print(u2.token)               # xyz789

Если у класса есть атрибут с тем же именем, после удаления атрибута экземпляра обращение вернет значение класса. Это удобно для сброса настройки к значению по умолчанию.

class Button:
    color = 'gray'           # значение по умолчанию

b = Button()
b.color = 'red'
print(b.color)               # red
delattr(b, 'color')
print(b.color)               # gray

Удаление атрибута класса

Если передать в delattr() сам класс, атрибут исчезнет у класса и, соответственно, у всех его экземпляров, которые не имеют собственного атрибута с таким именем.

class Coordinate:
    x = 10
    y = -5
    z = 0

point = Coordinate()
print(point.x, point.y, point.z)   # 10 -5 0

delattr(Coordinate, 'z')
print(point.x, point.y)            # 10 -5
print(point.z)                     # AttributeError

Обратное не работает: удалить атрибут класса через экземпляр нельзя. Вызов delattr(point, 'x') вызовет AttributeError, потому что в point.__dict__ такого ключа нет. Подробнее о том, где хранятся атрибуты, рассказано в статье о классах и объектах.

delattr() или del

Обе записи выполняют одно и то же и вызывают метод __delattr__ объекта. Разница только в том, как задается имя.

Критерийdel obj.attrdelattr(obj, name)
Имя атрибутаПишется в кодеСтрока, может быть в переменной
ЧитаемостьВышеНиже
Удаление по списку именНевозможно без evalЕстественно в цикле
СкоростьЧуть быстрееЕсть накладные расходы на вызов функции

Правило выбора: если имя атрибута известно при написании кода, используйте del. delattr() нужен, когда имя приходит из данных: из конфигурации, списка полей, ответа API.

class Profile:
    def __init__(self):
        self.login = 'anna'
        self.password = 'secret'
        self.phone = '+7 900 000-00-00'

private_fields = ['password', 'phone']
p = Profile()
for field in private_fields:
    if hasattr(p, field):
        delattr(p, field)
print(vars(p))   # {'login': 'anna'}

Ошибки и ограничения

delattr() выбрасывает исключение, если удалить атрибут нельзя. Основные случаи:

Чтобы удаление отсутствующего атрибута не роняло программу, проверьте его заранее через hasattr() или перехватите исключение:

try:
    delattr(obj, 'cache')
except AttributeError:
    pass   # атрибута не было, ничего делать не нужно

Объекты классов с __slots__ атрибуты удалять позволяют: слот остается, но становится пустым, и чтение после удаления дает AttributeError до следующего присваивания.

Метод __delattr__ и защита атрибутов

При любом удалении атрибута, через del или через delattr(), Python вызывает метод __delattr__(self, name). Переопределив его, можно запретить удаление важных полей, записать событие в журнал или очистить связанные данные. Внутри метода фактическое удаление выполняют вызовом super().__delattr__(name), иначе атрибут останется на месте.

class Config:
    protected = {'db_url'}

    def __init__(self):
        self.db_url = 'sqlite:///app.db'
        self.debug = True

    def __delattr__(self, name):
        if name in self.protected:
            raise AttributeError(f'Нельзя удалить {name}')
        print('Удаляю', name)
        super().__delattr__(name)

cfg = Config()
delattr(cfg, 'debug')    # Удаляю debug
del cfg.db_url           # AttributeError: Нельзя удалить db_url

Не пишите внутри __delattr__ конструкцию del self.name: она снова вызовет __delattr__ и приведет к бесконечной рекурсии. Описание функции есть в официальной документации.

Где delattr() применяется на практике

В прикладном коде функция встречается нечасто, но в нескольких ситуациях без нее не обойтись:

from functools import cached_property

class Report:
    @cached_property
    def total(self):
        print('считаю...')
        return 42

r = Report()
r.total            # считаю...
r.total            # берется из кеша
delattr(r, 'total')
r.total            # считаю... (пересчет)

Частые вопросы

Ответы на вопросы о функции delattr().

Что возвращает delattr()?

Ничего, результат равен None. Об успехе говорит отсутствие исключения, проверить результат можно через hasattr().

Можно ли удалить метод класса через delattr()?

Да, метод является атрибутом класса: delattr(MyClass, 'method_name'). После этого вызов метода у любых экземпляров даст AttributeError, если метод не унаследован от родителя.

Можно ли удалить переменную модуля?

Можно, модуль тоже объект: delattr(module, 'name'). Для глобальной переменной текущего модуля проще написать del name.

Чем delattr() отличается от присваивания None?

При присваивании None атрибут остается и hasattr() возвращает True. После delattr() атрибута нет совсем, а обращение к нему вызывает AttributeError или возвращает значение из класса.