ZetCode

Python vars 函数

上次修改时间:2025 年 4 月 11 日

本综合指南探讨 Python 的 vars 函数,该函数返回对象的 __dict__ 属性。我们将介绍对象、模块、命名空间和属性自省的实际示例。

基本定义

当使用参数调用时,vars 函数返回对象的 __dict__ 属性。没有参数时,它的行为类似于 locals()

主要特点:适用于具有 __dict__ 属性的对象、模块和类。在没有参数的情况下调用时,返回命名空间符号的字典。

基本对象用法

这是一个使用不同对象的简单示例,展示了 vars 如何通过 __dict__ 属性访问它们的属性。

basic_vars.py
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

p = Person("John", 30)
print(vars(p))  # {'name': 'John', 'age': 30}

# Adding a new attribute
p.job = "Developer"
print(vars(p))  # {'name': 'John', 'age': 30, 'job': 'Developer'}

此示例显示了带有自定义对象的 vars。它返回实例属性的字典。当我们添加一个新属性时,它会出现在后续的 vars 调用中。

输出与对象的 __dict__ 属性匹配,该属性存储实例的可写属性。

模块命名空间检查

vars 可以检查模块命名空间,显示所有定义的符号。此示例演示了模块自省。

module_vars.py
import math

# Get module attributes
math_vars = vars(math)
print("PI:", math_vars['pi'])  # PI: 3.141592653589793
print("Square root function:", math_vars['sqrt'])  # <built-in function sqrt>

# Filter constants only
constants = {k:v for k,v in math_vars.items() if not callable(v)}
print("Math constants:", constants.keys())

这展示了 vars 如何访问模块的命名空间。我们可以检索特定值或按类型过滤属性。

模块命名空间包含函数和常量,我们可以使用字典推导式将它们分开。

类属性

vars 可以检查类属性,在使用正确时显示类级别和实例级别的属性。

class_vars.py
class Vehicle:
    wheels = 4  # Class attribute
    
    def __init__(self, color):
        self.color = color  # Instance attribute

print("Class vars:", vars(Vehicle))  # Includes wheels
car = Vehicle("red")
print("Instance vars:", vars(car))   # Only color

该示例演示了类属性和实例属性之间的区别。类属性出现在 vars(Vehicle) 中,而实例属性出现在 vars(car) 中。

在处理类层次结构和属性查找链时,这种区别非常重要。

无参数行为

当没有参数调用时,vars 返回本地命名空间,类似于 locals()。此示例显示了该行为。

no_args_vars.py
def test_function():
    x = 10
    y = 20
    print("Local vars:", vars())

test_function()  # Shows x and y in local namespace

# At module level
a = 100
b = 200
print("Module vars:", vars())  # Shows a, b, and other module-level names

这演示了 vars() 返回当前的本地命名空间。在函数中,它显示局部变量。在模块级别,它显示全局变量。

该行为与 locals() 相同,但在这种形式中较少使用。

错误情况

vars 与没有 __dict__ 的对象一起使用时,会引发 TypeError。此示例显示了正确的错误处理。

errors.py
# Built-in types typically don't have __dict__
try:
    print(vars(10))
except TypeError as e:
    print(f"Error: {e}")  # vars() argument must have __dict__ attribute

class NoDict:
    __slots__ = ['x']  # Uses slots instead of __dict__

try:
    nd = NoDict()
    print(vars(nd))
except TypeError as e:
    print(f"Error: {e}")  # vars() argument must have __dict__ attribute

这些示例演示了 vars 对不受支持的类型的行为。具有 __slots__ 的内置类型和类通常不支持 vars

要检查对象是否支持 vars,您可以使用 hasattr(obj, '__dict__')

最佳实践

资料来源

作者

我叫 Jan Bodnar,我是一位热情的程序员,拥有丰富的编程经验。自 2007 年以来,我一直在撰写编程文章。到目前为止,我已经撰写了 1,400 多篇文章和 8 本电子书。我拥有超过十年的编程教学经验。

列出所有 Python 教程