← Назад к вопросам
Как посмотреть атрибуты объекта?
2.0 Middle🔥 171 комментариев
#Python Core#Soft Skills
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Просмотр атрибутов объекта в Python
Этот вопрос о интроспекции (introspection) — способности программы анализировать самой себя. Существует много способов посмотреть атрибуты объекта.
1. Функция dir() — самый простой способ
class Person:
class_var = "я переменная класса"
def __init__(self, name: str):
self.name = name
self._private = "приватное"
def greet(self):
return f"Hello, {self.name}"
person = Person("Alice")
# dir() показывает ВСЕ атрибуты и методы
attributes = dir(person)
print(attributes)
# [__class__, __delattr__, __dict__, __dir__, __doc__, __eq__,
# __format__, __ge__, __getattribute__, __gt__, __hash__, __init__,
# __init_subclass__, __le__, __lt__, __module__, __ne__, __new__,
# __reduce__, __reduce_ex__, __repr__, __setattr__, __sizeof__,
# __str__, __subclass_hook__, __weakref__, _private, class_var,
# greet, name]
2. __dict__ — словарь атрибутов экземпляра
person = Person("Alice")
# Показывает только атрибуты ЭКЗЕМПЛЯРА (не класса)
print(person.__dict__)
# {name: Alice, _private: приватное}
# Для класса:
print(Person.__dict__)
# {__module__: __main__, __doc__: None, class_var: ...,
# __init__: <function>, greet: <function>, ...}
3. vars() — альтернатива __dict__
print(vars(person)) # То же самое что person.__dict__
# {name: Alice, _private: приватное}
print(vars(Person)) # То же самое что Person.__dict__
4. getattr() и hasattr() — проверка атрибутов
# Проверка наличия
if hasattr(person, "name"):
print("У объекта есть атрибут name")
if hasattr(person, "nonexistent"):
print("Не выведется")
else:
print("Атрибута нет")
# Получение значения
name = getattr(person, "name")
print(name) # Alice
# С дефолтом
age = getattr(person, "age", 25)
print(age) # 25 (дефолт, потому что нет атрибута age)
5. setattr() и delattr() — изменение атрибутов
# Установка нового атрибута
setattr(person, "age", 30)
print(person.age) # 30
print(person.__dict__) # {name: Alice, _private: ..., age: 30}
# Удаление атрибута
delattr(person, "age")
print(hasattr(person, "age")) # False
6. Различие между атрибутами
class Example:
class_var = "класс" # Атрибут класса
def __init__(self):
self.instance_var = "экземпляр" # Атрибут экземпляра
def method(self):
local_var = "локальная" # Локальная переменная (НЕ атрибут)
return local_var
obj = Example()
# Атрибуты объекта
print(dir(obj)) # Включает class_var, instance_var, method и встроенные
# Только атрибуты ЭКЗЕМПЛЯРА
print(obj.__dict__) # {instance_var: экземпляр}
# Только атрибуты КЛАССА
print(Example.__dict__.keys()) # dict_keys([__module__, __doc__,
# class_var, __init__, method, ...])
# Поиск атрибута: сначала в экземпляре, потом в классе
print(obj.class_var) # "класс" (найден в классе)
print(obj.instance_var) # "экземпляр" (найден в экземпляре)
7. Фильтрация атрибутов
# Только пользовательские атрибуты (без магических __...__)
user_attrs = [attr for attr in dir(obj) if not attr.startswith("_")]
print(user_attrs) # [class_var, greet, instance_var, name]
# Только методы
methods = [attr for attr in dir(obj) if callable(getattr(obj, attr))]
print(methods) # [greet, count, index, ...]
# Только свойства (property)
properties = [attr for attr in dir(type(obj))
if isinstance(getattr(type(obj), attr), property)]
# Только атрибуты, не начинающиеся с нижнего подчёркивания
public_attrs = {k: v for k, v in obj.__dict__.items()
if not k.startswith("_")}
print(public_attrs) # {name: Alice}
8. inspect модуль — для глубокого анализа
import inspect
class Calculator:
def add(self, a: int, b: int) -> int:
"""Сложение двух чисел."""
return a + b
def multiply(self, a: int, b: int) -> int:
"""Умножение двух чисел."""
return a * b
calc = Calculator()
# Получить сигнатуру метода
sig = inspect.signature(calc.add)
print(sig) # (a: int, b: int) -> int
print(sig.parameters) # OrderedDict([(a, <Parameter>), (b, <Parameter>)])
# Получить параметры
for param_name, param in sig.parameters.items():
print(f"{param_name}: {param.annotation}")
# a: <class int>
# b: <class int>
# Получить docstring
print(inspect.getdoc(calc.add)) # "Сложение двух чисел."
# Все методы класса
members = inspect.getmembers(calc, predicate=inspect.ismethod)
for name, method in members:
print(f"{name}: {method}")
# Исходный код метода
print(inspect.getsource(calc.add))
# def add(self, a: int, b: int) -> int:
# """Сложение двух чисел."""
# return a + b
# Информация о классе
print(inspect.getmembers(Calculator, predicate=inspect.isfunction))
9. type() — получить тип объекта
person = Person("Alice")
# Тип объекта
print(type(person)) # <class __main__.Person>
print(type(person).__name__) # Person
# MRO — Method Resolution Order (порядок поиска методов)
print(type(person).__mro__) # (<class Person>, <class object>)
# Базовые классы
print(type(person).__bases__) # (<class object>,)
10. __class__ и __mro__ для наследования
class Animal:
pass
class Dog(Animal):
pass
dog = Dog()
# Класс объекта
print(dog.__class__) # <class __main__.Dog>
print(dog.__class__.__name__) # Dog
# MRO — порядок поиска методов
print(Dog.__mro__) # (<class Dog>, <class Animal>, <class object>)
# Проверка типа
print(isinstance(dog, Dog)) # True
print(isinstance(dog, Animal)) # True
print(isinstance(dog, object)) # True
11. Встроенные атрибуты (dunder)
class MyClass:
def __init__(self):
self.x = 1
def __repr__(self):
return f"MyClass(x={self.x})"
def __str__(self):
return f"My object with x={self.x}"
obj = MyClass()
# Магические методы
print(obj.__class__) # <class __main__.MyClass>
print(obj.__dict__) # {x: 1}
print(obj.__module__) # __main__
print(obj.__doc__) # None или docstring класса
print(obj.__repr__()) # MyClass(x=1)
print(obj.__str__()) # My object with x=1
print(obj.__sizeof__()) # Размер в памяти
12. Полный пример интроспекции
import inspect
class DataClass:
class_var = "Я переменная класса"
def __init__(self, name: str, age: int):
self.name = name
self.age = age
self._private = "Приватное"
def public_method(self):
"""Публичный метод."""
return f"Hello, {self.name}"
def _private_method(self):
return "Приватный метод"
@property
def info(self):
"""Property для получения информации."""
return f"{self.name} ({self.age})"
obj = DataClass("Alice", 30)
def introspect(obj):
"""Полная интроспекция объекта."""
print("=== АТРИБУТЫ ===")
print(f"__dict__: {obj.__dict__}")
print("\n=== МЕТОДЫ ===")
for name in dir(obj):
if not name.startswith("_"):
attr = getattr(obj, name)
if callable(attr):
print(f" {name}(): {inspect.getdoc(attr)}")
print("\n=== PROPERTIES ===")
for name in dir(type(obj)):
if not name.startswith("_"):
attr = getattr(type(obj), name)
if isinstance(attr, property):
print(f" {name} (property)")
print("\n=== КЛАССОВЫЕ ПЕРЕМЕННЫЕ ===")
for name, value in type(obj).__dict__.items():
if not name.startswith("_") and not callable(value) and not isinstance(value, property):
print(f" {name}: {value}")
print("\n=== ИЕРАРХИЯ ===")
print(f" Type: {type(obj)}")
print(f" MRO: {type(obj).__mro__}")
introspect(obj)
Сравнение методов
| Функция | Что показывает | Примечание |
|---|---|---|
dir() | ВСЕ атрибуты и методы | Включает магические методы |
__dict__ | Атрибуты экземпляра | Не включает атрибуты класса |
vars() | Альтернатива __dict__ | То же самое |
getattr() | Получить значение | С дефолтом |
hasattr() | Проверить наличие | Для проверки |
inspect | Глубокий анализ | Сигнатуры, исходный код |
type() | Тип объекта | Для определения класса |
isinstance() | Проверка типа | С учётом наследования |
Лучшие практики
✅ Для просмотра атрибутов:
dir()— быстрая проверкаvars()— атрибуты экземпляраinspect— серьёзный анализgetattr()— безопасное получение
❌ Избегай:
- Полагаться на
__dict__для всех атрибутов (свойства и методы не включены) - Прямого обращения к
__атрибутам (они могут измениться) - Модификации
__dict__вручную (используйsetattr)
Интроспекция — мощный инструмент для отладки, тестирования и создания универсального кода.