cpython中什么时候将类的tp_dict赋给对象
时间: 2023-06-15 11:04:24 浏览: 52
在CPython中,类的tp_dict在对象创建时会被赋值给对象的__dict__属性。也就是说,当我们使用类创建一个对象时,对象会继承类的tp_dict作为自己的属性字典,这样对象就可以访问类的所有属性和方法了。这个过程是在对象的tp_alloc函数中完成的。具体的实现可以参考CPython的源代码,例如在Objects/typeobject.c文件中的type_new函数中,有以下代码段:
```
/* Fill in tp_dict */
if (dict != NULL) {
Py_INCREF(dict);
type->tp_dict = dict;
if (op->tp_flags & Py_TPFLAGS_HEAPTYPE)
PyDict_SetItemString(dict, "__module__", str);
}
else {
type->tp_dict = PyDict_New();
if (op->tp_flags & Py_TPFLAGS_HEAPTYPE) {
PyDict_SetItemString(type->tp_dict, "__module__", str);
}
}
```
可以看到,如果类的字典不为空,就直接将类的字典赋值给对象的tp_dict属性;如果类的字典为空,则新建一个字典,并将其赋值给对象的tp_dict属性。
相关问题
cpython中对象的tp_dict从哪儿产生?
在Python中,每个对象都有一个字典,用于存储对象的属性和方法。这个字典被称为“实例字典”或“命名空间字典”。
对于新创建的对象,其实例字典是在对象创建时动态创建的。具体来说,在创建对象时,Python解释器会根据对象的类型(即对象所属的类)从类型的__dict__属性中获取一个字典对象,然后把这个字典对象作为对象的实例字典。这个字典对象被称为“类字典”或“命名空间字典”。
在CPython中,对象的tp_dict是通过PyTypeObject结构体中的tp_dictoffset字段来访问的。当创建一个新对象时,它的tp_dict指向其所属类型的tp_dict。如果对象所属的类型没有定义tp_dict,则该对象没有实例字典。如果对象本身定义了__dict__属性,则它的实例字典将存储在这个属性中。
cpython中类成员和属性分别是如何实现
在 CPython 中,类成员和属性是通过描述符(descriptor)来实现的。描述符是一种实现特定协议的对象,这个协议包括了访问类成员和属性的方法。常用的描述符有:
1. 数据描述符(data descriptor):实现了 `__get__`、`__set__` 或 `__delete__` 中的至少一个方法的描述符。数据描述符可以完全控制属性的访问。
2. 非数据描述符(non-data descriptor):实现了 `__get__` 方法,但没有实现 `__set__` 或 `__delete__` 方法的描述符。非数据描述符只能控制属性的访问,但不能修改属性的值。
3. 实例成员(instance member):定义在类中的变量,每个实例都会拥有自己的一份。
4. 类成员(class member):定义在类中的变量,所有实例共享一份。
当访问类成员时,Python 会先检查实例是否有同名的属性,如果没有则会查找类成员。如果类成员是描述符,则会调用描述符的对应方法。如果类成员不是描述符,则直接返回该变量的值。同样,当访问属性时,Python 会先检查实例是否有同名的属性,如果没有则会查找类的 `__dict__` 属性中是否有同名的描述符,如果找到则调用描述符的 `__get__` 方法,否则直接返回 `__getattr__` 方法的返回值。
总的来说,在 CPython 中,类成员和属性都是通过描述符来实现的。描述符可以完全控制属性的访问,包括读取、修改和删除。同时,Python 还提供了实例成员和类成员两种变量类型,方便开发者进行对象和类级别的数据管理。
相关推荐
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![so](https://img-home.csdnimg.cn/images/20210720083646.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)