Vars: примеры (PYTHON)
vars([object]): dictОсновы функции vars
Функция vars() возвращает атрибут __dict__ переданного объекта. Этот атрибут содержит словарь, который хранит изменяемые атрибуты объекта. Функция применяется для интроспекции объектов и получения информации об их текущем состоянии.
Синтаксис функции:
vars([object])
Параметр object может быть модулем, классом, экземпляром или любым другим объектом, имеющим атрибут __dict__. Если параметр не указан, функция возвращает словарь с переменными локальной области видимости, аналогично вызову locals().
Возвращаемое значение:
- Если объект имеет атрибут
__dict__, возвращается этот атрибут - Для модулей возвращаются их глобальные символы
- Для классов возвращаются пространства имен, поддерживающие динамическое назначение атрибутов
- Для экземпляров классов возвращаются атрибуты экземпляра
- Без аргументов возвращается локальное пространство имен
Базовые примеры использования
Пример с модулем:
import math
print(vars(math)['pi'])3.141592653589793
Пример с классом:
class MyClass:
class_attr = 100
def __init__(self):
self.instance_attr = 200
print(vars(MyClass)){'__module__': '__main__', 'class_attr': 100, '__init__': , ...} Пример с экземпляром класса:
obj = MyClass()
print(vars(obj)){'instance_attr': 200}Пример без аргументов:
x = 10
y = 20
print(vars()){'x': 10, 'y': 20, '__builtins__': {...}, ...}Похожие функции в Python
locals() возвращает словарь с переменными локальной области видимости. Функция vars() без аргументов ведет себя аналогично, но locals() нельзя использовать для изменения переменных.
globals() возвращает словарь с глобальными переменными текущего модуля. Отличается от vars(module) тем, что работает в контексте текущего модуля без необходимости его импортировать.
dir() возвращает список имен атрибутов объекта, но без их значений. Полезен для получения перечня доступных атрибутов.
getattr(), setattr(), hasattr() работают с отдельными атрибутами объектов, тогда как vars() предоставляет доступ ко всем атрибутам одновременно.
Аналоги в других языках программирования
JavaScript: Объекты можно исследовать с помощью Object.keys(), Object.values() или Object.entries().
const obj = {a: 1, b: 2};
console.log(Object.entries(obj));[['a', 1], ['b', 2]]
PHP: Функция get_object_vars() возвращает свойства объекта.
class MyClass {
public $a = 1;
private $b = 2;
}
$obj = new MyClass();
print_r(get_object_vars($obj));Array ( [a] => 1 )
Java: Рефлексия через getClass().getDeclaredFields() позволяет получить поля класса.
import java.lang.reflect.*;
public class Main {
public int x = 5;
public static void main(String[] args) throws Exception {
Main obj = new Main();
Field[] fields = obj.getClass().getDeclaredFields();
for (Field field : fields) {
System.out.println(field.getName() + " = " + field.get(obj));
}
}
}x = 5
C#: Свойства объекта можно получить через рефлексию с использованием GetType().GetProperties().
using System;
using System.Reflection;
class Program {
public int Value { get; set; } = 42;
static void Main() {
var obj = new Program();
var props = obj.GetType().GetProperties();
foreach (var prop in props) {
Console.WriteLine($"{prop.Name}: {prop.GetValue(obj)}");
}
}
}Value: 42
Типичные ошибки
Вызов для объектов без атрибута __dict__:
print(vars(10))TypeError: vars() argument must have __dict__ attribute
Использование с объектами, у которых атрибут __dict__ недоступен:
import numpy as np
arr = np.array([1, 2, 3])
print(vars(arr))AttributeError: 'numpy.ndarray' object has no attribute '__dict__'
Попытка изменения локальных переменных через результат vars():
def test():
x = 1
d = vars()
d['x'] = 2 # Не рекомендуется
print(x)
test()1 # Изменение не повлияло на фактическую переменную
Изменения в последних версиях Python
В Python 3.10 и 3.11 функция vars() не претерпела существенных изменений. Однако в Python 3.7 было уточнено поведение функции: при вызове без аргументов в интерактивной среде возвращаются переменные локального контекста, а не глобального пространства имен модуля.
Начиная с Python 3.6, объекты типа module имеют упорядоченный словарь атрибутов, что отражается на порядке элементов в результате vars(module).
Расширенные примеры использования
Динамическое добавление атрибутов через vars():
class DynamicObject:
pass
obj = DynamicObject()
vars(obj)['new_attribute'] = 'dynamic value'
print(obj.new_attribute)dynamic value
Использование с декораторами для интроспекции:
def debug_methods(cls):
for name, method in vars(cls).items():
if callable(method):
print(f"Method: {name}")
return cls
@debug_methods
class MyClass:
def method1(self):
pass
def method2(self):
passMethod: method1 Method: method2
Сравнение объектов через их атрибуты:
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def compare_objects(obj1, obj2):
return vars(obj1) == vars(obj2)
p1 = Point(1, 2)
p2 = Point(1, 2)
p3 = Point(3, 4)
print(compare_objects(p1, p2))
print(compare_objects(p1, p3))True False
Сериализация объектов в JSON:
import json
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
person = Person("Alice", 30)
json_data = json.dumps(vars(person))
print(json_data){"name": "Alice", "age": 30}Работа со слотами:
class SlottedClass:
__slots__ = ['x', 'y']
def __init__(self):
self.x = 10
self.y = 20
obj = SlottedClass()
# print(vars(obj)) # Вызовет ошибку
print({slot: getattr(obj, slot) for slot in SlottedClass.__slots__}){'x': 10, 'y': 20}Интроспекция встроенных типов:
import datetime
now = datetime.datetime.now()
print(list(vars(now).keys())[:5])['year', 'month', 'day', 'hour', 'minute']
Изменение атрибутов модуля:
import sys
# Добавление кастомного атрибута в модуль sys
vars(sys)['custom_attr'] = 'test'
print(sys.custom_attr)test