← Назад к вопросам
Как получить список атрибутов объекта в Python?
1.0 Junior🔥 121 комментариев
#Python Core
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Получение списка атрибутов объекта в Python
Python предоставляет несколько способов интроспекции для получения информации об атрибутах объекта. Выбор зависит от конкретного использования.
1. dir() — наиболее распространённый способ
class Person:
class_attr = 'class attribute'
def __init__(self, name, age):
self.name = name
self.age = age
def greet(self):
return f'Hello, {self.name}'
person = Person('Alice', 30)
# Получить все атрибуты (включая методы и dunder attributes)
all_attrs = dir(person)
print(all_attrs)
# ['__class__', '__delattr__', '__doc__', ..., 'age', 'class_attr', 'greet', 'name']
# Отфильтровать только пользовательские атрибуты (без dunder)
user_attrs = [attr for attr in dir(person) if not attr.startswith('_')]
print(user_attrs) # ['age', 'class_attr', 'greet', 'name']
2. dict — только атрибуты экземпляра
person = Person('Alice', 30)
# Получить словарь атрибутов экземпляра
print(person.__dict__) # {'name': 'Alice', 'age': 30}
print(Person.__dict__) # Словарь класса с методами
# Получить ключи (имена атрибутов)
attribute_names = list(person.__dict__.keys())
print(attribute_names) # ['name', 'age']
3. vars() — удобная обёртка для dict
person = Person('Alice', 30)
# vars() возвращает __dict__
print(vars(person)) # {'name': 'Alice', 'age': 30}
# Эквивалентно
print(person.__dict__) # Одно и то же
# vars() работает и на классах
print(vars(Person)) # Большой словарь с методами и атрибутами класса
4. getattr() — получить конкретный атрибут
person = Person('Alice', 30)
# Получить атрибут с дефолтным значением
name = getattr(person, 'name') # 'Alice'
city = getattr(person, 'city', 'Moscow') # 'Moscow' (не существует, используется дефолт)
# Без дефолта — выбросит AttributeError
try:
city = getattr(person, 'city')
except AttributeError:
print('Атрибут не существует')
5. hasattr() — проверка наличия атрибута
person = Person('Alice', 30)
if hasattr(person, 'name'):
print(person.name) # Alice
if hasattr(person, 'city'):
print(person.city) # Не выполнится
else:
print('Нет атрибута city')
# Получить только существующие атрибуты
existing_attrs = [attr for attr in dir(person) if hasattr(person, attr)]
6. inspect модуль — для детальной информации
import inspect
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def greet(self):
return f'Hello, {self.name}'
@property
def is_adult(self):
return self.age >= 18
person = Person('Alice', 30)
# Получить все члены (attributes + methods)
members = inspect.getmembers(person)
for name, value in members:
if not name.startswith('_'):
print(f"{name}: {type(value).__name__}")
# Вывод:
# age: int
# greet: method
# is_adult: bool (property)
# name: str
# Разделить на разные типы
print("\nAttributes:")
for name, value in inspect.getmembers(person):
if not callable(value) and not name.startswith('_'):
print(f"{name}: {value}")
print("\nMethods:")
for name, value in inspect.getmembers(person):
if callable(value) and not name.startswith('_'):
print(f"{name}")
print("\nProperties:")
for name, value in inspect.getmembers(Person):
if isinstance(value, property):
print(f"{name}")
7. Типизированные атрибуты (для dataclass и TypedDict)
from dataclasses import dataclass, fields
from typing import TypedDict
@dataclass
class PersonData:
name: str
age: int
email: str = 'unknown'
# Получить информацию о полях dataclass
for field in fields(PersonData):
print(f"{field.name}: {field.type}")
# Вывод:
# name: <class 'str'>
# age: <class 'int'>
# email: <class 'str'>
# Для TypedDict
class PersonDict(TypedDict):
name: str
age: int
# Получить аннотации типов
print(PersonDict.__annotations__)
# {'name': <class 'str'>, 'age': <class 'int'>}
8. annotations — для получения типов
class Person:
name: str
age: int
def __init__(self, name: str, age: int):
self.name = name
self.age = age
# Получить аннотации типов класса
print(Person.__annotations__)
# {'name': <class 'str'>, 'age': <class 'int'>}
# Для функций
def greet(name: str, age: int) -> str:
return f'Hello {name}'
print(greet.__annotations__)
# {'name': <class 'str'>, 'age': <class 'int'>, 'return': <class 'str'>}
9. Практический пример: Классификация атрибутов
import inspect
class AttributeAnalyzer:
@staticmethod
def analyze(obj):
"""Детально проанализировать все атрибуты объекта"""
result = {
'instance_attributes': {},
'class_attributes': {},
'methods': {},
'properties': {},
}
# Атрибуты экземпляра
if hasattr(obj, '__dict__'):
result['instance_attributes'] = dict(obj.__dict__)
# Через inspect
for name, value in inspect.getmembers(obj):
if name.startswith('_'):
continue
if isinstance(value, property):
result['properties'][name] = str(value)
elif callable(value):
result['methods'][name] = inspect.signature(value)
elif not isinstance(value, (type, type(obj.__class__))):
# Атрибут класса
result['class_attributes'][name] = value
return result
class Person:
class_var = 'class attribute'
def __init__(self, name, age):
self.name = name
self.age = age
def greet(self):
return f'Hi, {self.name}'
@property
def is_adult(self):
return self.age >= 18
person = Person('Alice', 30)
analysis = AttributeAnalyzer.analyze(person)
print("Instance Attributes:", analysis['instance_attributes'])
print("Class Attributes:", analysis['class_attributes'])
print("Methods:", analysis['methods'].keys())
print("Properties:", analysis['properties'].keys())
10. Сравнение методов
| Метод | Возвращает | Включает dunder | Включает методы | Скорость |
|---|---|---|---|---|
| dir() | Список | Да | Да | Медленнее |
| dict | Словарь | Нет | Нет (только instance) | Быстро |
| vars() | Словарь | Нет | Нет | Быстро |
| inspect.getmembers() | Список кортежей | Да | Да | Медленнее |
| getattr() | Одно значение | - | - | Очень быстро |
| annotations | Словарь типов | Нет | Нет | Быстро |
11. Best Practices
# ✅ Для быстрого доступа к атрибутам экземпляра
instance_attrs = vars(obj) # или obj.__dict__
# ✅ Для получения всех, включая методы
all_attrs = dir(obj)
# ✅ Для информации о типах
attributes_with_types = inspect.getmembers(obj)
# ✅ Для динамического доступа
value = getattr(obj, 'attribute_name', default_value)
# ✅ Для типизированного кода
from dataclasses import fields
field_names = [f.name for f in fields(MyDataClass)]
# ❌ Избегать
del obj.__dict__['attr'] # Прямое редактирование — плохая практика
# ✅ Вместо этого
delattr(obj, 'attr')
12. Экспортировать в JSON
import json
def object_to_dict(obj):
"""Сериализовать объект в словарь"""
if hasattr(obj, '__dict__'):
return obj.__dict__
elif hasattr(obj, '__iter__'):
return list(obj)
else:
return str(obj)
person = Person('Alice', 30)
person_dict = object_to_dict(person)
json_str = json.dumps(person_dict, indent=2)
print(json_str)
# Вывод:
# {
# "name": "Alice",
# "age": 30
# }
Выбирай метод в зависимости от задачи: dir() для общего списка, dict для быстрого доступа, inspect для детальной информации.