vars()本质是obj.__dict__的安全封装,仅对拥有__dict__的对象有效;对内置类型、__slots__类等无__dict__对象会抛typeerror,此时应改用hasattr或dir()+getattr组合。

vars() 能直接返回对象的 __dict__,但仅限于拥有该属性的对象——比如自定义类实例、模块、函数;内置类型(如 list、str、int)调用会报 TypeError: vars() argument must have __dict__ attribute。
什么时候 vars() 会抛错?
常见于对不可变或无 __dict__ 的对象调用:
-
vars([1, 2, 3])→ 报错,list实例不暴露__dict__ -
vars("hello")→ 报错,str是内置不可变类型 -
vars(42)→ 同样报错 - 空参数
vars()等价于locals(),只在函数内有效,全局作用域慎用
怎么安全地用 vars() 查看自定义对象?
确保对象是普通类实例,且没禁用 __dict__(比如用了 __slots__):
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
<p>p = Person("Alice", 30)
print(vars(p)) # {'name': 'Alice', 'age': 30}
</p>
- 如果类定义了
__slots__ = ['name', 'age'],vars(p)会直接报错 - 此时只能用
p.__dict__(不存在)或手动构造字典,vars()失效 - 模块对象可用:
vars(os)返回所有公开属性名(不含下划线开头的)
vars() 和 dir()、getattr() 的关键区别
vars() 只返回「可写属性」的当前值字典,不是所有可见名:
-
dir(p)返回所有属性+方法名列表(含继承的、双下划线的),但不带值 -
vars(p)只返回实例字典里真实存在的键值对,不含方法、类属性、父类属性 - 想查某个属性是否存在且有值?优先用
hasattr(p, 'name')+getattr(p, 'name', None),比vars()更健壮 -
vars()不递归,不会展开嵌套对象,也不处理 property 或描述符——它们若没被赋值到__dict__,就不会出现在结果里
真正要注意的是:别把它当万能反射工具。它只是 __dict__ 的快捷入口,而 Python 对象的属性来源远不止这一处。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











