【问题标题】:Does Python Objects internally stored as Dictionaries? [duplicate]Python 对象是否在内部存储为字典? [复制]
【发布时间】:2018-03-05 15:19:08
【问题描述】:

我可以像这样创建一个 python 对象

class Test:
   pass

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

并且可以使用查看对象的字典

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

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

【问题讨论】:

  • 这似乎特定于类实例;不是所有对象
  • 这次我没能找到骗子。所以这可能是一个很好的骗局。

标签: python python-3.x python-2.7


【解决方案1】:

简单说明

没有。但在内部,所有 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

基本原理

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

tldr

大多数情况下,是的。最理想的是,没有。使用__slots__ 来最小化你的类的大小。

【讨论】:

    猜你喜欢
    • 2023-03-28
    • 2016-09-24
    • 2021-05-08
    • 2019-02-19
    • 2021-04-15
    • 1970-01-01
    • 2018-08-23
    • 2011-09-17
    • 2019-08-29
    相关资源
    最近更新 更多