Python对象是否内部存储为字典?

2024-04-24 10:36:04 发布

您现在位置:Python中文网/ 问答频道 /正文

我可以创建这样的python对象

class Test:
   pass

t1 = Test()
t1.var = "value"
t1.num = 100

并且可以使用

print(t1.__dict__)
# prints
{'var': 'value', 'num': 100}

这是否意味着python对象在内部存储为字典?你知道吗


Tags: 对象test字典valuevarpassprintsnum
1条回答
网友
1楼 · 发布于 2024-04-24 10:36:04

简单的解释

不是。但是在内部,所有Python对象(除了那些用__slots__或Python内置定义的对象)都使用字典进行动态属性访问。你知道吗

正如您在下面的示例中所看到的,使用__slots__会使类型不存储内部字典,这会阻止为类型动态设置方法、字段或其他信息。但是,类型的大小因此而减小。你知道吗

In [7]: class A:
   ...:     __slots__ = ('fields')
   ...:     def __init__(self):
   ...:         self.fields = 1
   ...:       

In [9]: dir(A)
Out[9]: 
['__class__',
'__delattr__',
'__dir__',
'__doc__',
'__eq__',
'__format__',
'__ge__',
'__getattribute__',
'__gt__',
'__hash__',
'__init__',
'__init_subclass__',
'__le__',
'__lt__',
'__module__',
'__ne__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__setattr__',
'__sizeof__',
'__slots__',
'__str__',
'__subclasshook__',
'fields']

如果您查看一下CPython源代码code,您还将看到大多数内置类型都没有存储为字典,或者:

#ifndef Py_LIMITED_API
typedef struct {
    PyObject_HEAD
    double ob_fval;
} PyFloatObject;
#endif

基本原理

为了理解为什么所有允许动态设置变量、方法和其他信息的类都在内部使用dict来存储这些信息,我们需要考虑哪些字典非常擅长:O(1)通过O(1)插入和删除来访问信息。由于解释器在运行时之前不知道类可能具有哪些属性,如果该属性是变量、方法等,则需要在运行时使用绑定到类的某种容器。在其他语言中,如C++,这是通过使用函数指针数组(通常是不保证的)或虚拟表来实现的,允许您动态地将预定义的方法集更改为类。但是,由于方法名已经硬编码,因此不允许动态地向类中添加或删除方法。除了hashmap或二进制搜索树之外的任何方法都可能无法有效地允许动态类型。你知道吗

tldr公司

基本上,是的。最好不要这样做。使用__slots__来最小化类的大小。你知道吗

相关问题 更多 >