Vars: примеры (PYTHON)

Функция 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():

Пример python
class DynamicObject:
    pass

obj = DynamicObject()
vars(obj)['new_attribute'] = 'dynamic value'
print(obj.new_attribute)
dynamic value

Использование с декораторами для интроспекции:

Пример python
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):
        pass
Method: method1
Method: method2

Сравнение объектов через их атрибуты:

Пример python
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:

Пример python
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}

Работа со слотами:

Пример python
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}

Интроспекция встроенных типов:

Пример python
import datetime
now = datetime.datetime.now()
print(list(vars(now).keys())[:5])
['year', 'month', 'day', 'hour', 'minute']

Изменение атрибутов модуля:

Пример python
import sys
# Добавление кастомного атрибута в модуль sys
vars(sys)['custom_attr'] = 'test'
print(sys.custom_attr)
test

питон vars function comments

En
Vars Return __dict__ attribute