说明
《Python 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
Python 的内置函数 vars() 返回对象的属性和属性值的字典对象。如果没有参数,就返回当前调用位置的属性和属性值,行为类似 locals()。
以下是这一些快速应用的案例:
# 在终端输入
vars()
# 输出(已美化格式)
{'__name__': '__main__',
'__doc__': None,
'__package__': None,
'__loader__': <class '_frozen_importlib.BuiltinImporter'>,
'__spec__': None,
'__annotations__': {},
'__builtins__': <module 'builtins' (built-in)>
}
# 1 对象没有__dict__ 属性
vars(1)
# TypeError: vars() argument must have __dict__ attribute
class Foo:
def __init__(self):
self.__dict__ = {'name':'Foo'}
f = Foo()
vars(f)
# {'name': 'Foo'}
# 再终端执行
vars()
# 输出(已美化格式)
{'__name__': '__main__',
'__doc__': None,
'__package__': None,
'__loader__': <class '_frozen_importlib.BuiltinImporter'>,
'__spec__': None,
'__annotations__': {},
'__builtins__': <module 'builtins' (built-in)>,
'Foo': <class '__main__.Foo'>,
'f': <__main__.Foo object at 0x7fccf35f5120>
}
# 注意最后两项
语法为 vars([object])
,其中对象可有可没有。来用返回模块、类、实例或任何其它具有 __dict__
属性的对象的 __dict__
属性。
模块和实例这样的对象具有可更新的 __dict__
属性;但是,其它对象的 __dict__
属性可能会设为限制写入(例如,类会使用 types.MappingProxyType 来防止直接更新字典)。
如果指定了一个对象但它没有 __dict__
属性(例如,当它所属的类定义了 __slots__
属性时)则会引发 TypeError 异常。
不带参数时,vars() 的行为类似 locals() ,locals() 用来更新并返回表示当前本地符号表的字典。 请注意,locals 字典仅对于读取起作用,因为对 locals 字典的更新会被忽略。
如,我们进行赋值操作时,如 bar = 1,执行赋值语句后,名称 bar 引用到值 1,名字为键,将我们要取这个值时,可以用 vars() 返回的字典里用此键取得其引用值:
bar = 1
vars()['bar']
# 1
'bar' in vars().keys()
# True
详见: locals() 的介绍。
__dict__
类的静态函数、类函数、普通函数、全局变量以及一些内置的属性都是放在类的 __dict__
里。一些内置的数据类型是没有 __dict__
属性的。
vars() 可以帮助我们动态地进行变量赋值,动态生成变量。例如:
v = vars()
for i in range(3):
v[f'my_{i}'] = i
# 批量生成三个变量并赋值
my_0 # 0
my_1 # 1
my_2 # 2
vars()
'''
{..., 'v': {...},
'my_0': 1, 'my_1': 1, 'my_2': 1}
'''
在 Python 内置模块 enum 官方文档中有这样的一个示例:
from datetime import timedelta
from enum import Enum
class Period(timedelta, Enum):
"different lengths of time"
_ignore_ = 'Period i'
Period = vars()
for i in range(367):
Period['day_%d' % i] = i
Period.day_10
# <Period.day_10: datetime.timedelta(days=10)>
[*Period]
# 输出(省略部分)
[<Period.day_0: datetime.timedelta(0)>,
<Period.day_1: datetime.timedelta(days=1)>,
<Period.day_2: datetime.timedelta(days=2)>,
<Period.day_3: datetime.timedelta(days=3)>,
...
<Period.day_365: datetime.timedelta(days=365)>,
<Period.day_366: datetime.timedelta(days=366)>]
vars() 表示的是类定义内部的局部作用域,相当于:
class Period(timedelta, Enum):
"different lengths of time"
day_1 = timedelta(1)
day_2 = timedelta(2)
...
day_365 = timedelta(365)
day_366 = timedelta(366)
由于类定义内部是单独的作用域,因此用 globals 或者 locals 达不到相同的效果,而在类定义中,因为类名称还不可用,因此也无法用 setattr 实现。
__dict__
属性,大多数自定义类会隐式创建 __dict__
属性__dict__
属性,会报错:TypeError: vars() argument must have __dict__ attribute
Python globals() locals() vars() 三个内置函数的区别,可参考 locals() 的相关介绍。
更新时间:March 27, 2022, 11:02 a.m. 标签:python 属性 字典