Python “dict”和“weakref”是类定义中的默认插槽吗?
根据报告:Python “dict”和“weakref”是类定义中的默认插槽吗?,python,class,instance,python-internals,slots,Python,Class,Instance,Python Internals,Slots,根据报告: \uuuuuuuuuuuuuuuuuuuuuuuu允许我们显式声明数据成员(如属性)并拒绝创建\uuuuuuuuuuuuuuu dict\uuuuuuu和\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu 所以我想知道这门课 >>A类:槽位=(“指令”和“weakref”) ... >>>德尔A.。uu槽__ >>>vars(A) 映射代理({ “\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
\uuuuuuuuuuuuuuuuuuuuuuuu
允许我们显式声明数据成员(如属性)并拒绝创建\uuuuuuuuuuuuuuu dict\uuuuuuu
和\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
所以我想知道这门课
>>A类:槽位=(“指令”和“weakref”)
...
>>>德尔A.。uu槽__
>>>vars(A)
映射代理({
“\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu,
"条例":,,
"weakref":,,
“\uuuu doc\uuuuuuu”:无
})
与此等效:
>A类:合格
...
>>>vars(A)
映射代理({
“\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu,
"条例":,,
"weakref":,,
“\uuuu doc\uuuuuuu”:无
})
如果未设置\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
属性,默认设置为在特定条件下创建\
这种情况发生在类型中。_unew_uu()
;为每个实例提供了访问内存插槽的类描述符:
- 首先,通过测试类型对象结构中的、和值,检查类型是否可以具有这些插槽
- 如果基类尚未定义插槽(
base->tp\u dictoffset
为0),则只能有一个\u dict\u
插槽
- 如果基类型未定义插槽(
base->tp\u weaklistoffset
为0),并且基具有固定长度的实例(base->tp\u itemsize
为0),则只能拥有\uuuuuuuukref\uuuuuu
插槽
- 然后,如果没有
\uuuuuuuuuuuuuuu插槽
,则设置标志变量以实际启用要添加的插槽
代码很长,但相关部分如下所示:
slots=\u PyDict\u getitemidwerstror(dict,&PyId\uuuuu slots);
nslots=0;
加上_dict=0;
加上_弱=0;
may\u add\u dict=base->tp\u dict offset==0;
可以添加\u weak=base->tp\u weaklistoffset==0&&base->tp\u itemsize==0;
如果(插槽==NULL){
如果(Pyrr_发生()){
转到错误;
}
如果(可以添加命令){
添加_dict++;
}
如果(可以加上弱){
添加_弱++;
}
}
否则{
/*有空位*/
...
}
然后,向下大约400行,您将找到实际创建插槽的代码:
if(添加命令){
if(基本->tp\U项目大小)
类型->tp_dictoffset=-(长)sizeof(PyObject*);
其他的
类型->tp\u dictoffset=slotofset;
slotofset+=sizeof(PyObject*);
}
如果(添加弱){
断言(!base->tp_itemsize);
类型->tp_weaklistoffset=slotofset;
slotofset+=sizeof(PyObject*);
}
扩展某些本机类型(如int
或bytes
)时,您不会得到\uuuuuukref\uuuuu
插槽,因为它们具有可变长度的实例(由tp\uitemsize
处理)。如果您没有设置\uuuuuuuu-slots\uuu
属性,默认设置是在特定条件下创建\uuuuu weakref\uuuu
和\uuuu dict\uuuu
插槽
这种情况发生在类型中。_unew_uu()
;为每个实例提供了访问内存插槽的类描述符:
- 首先,通过测试类型对象结构中的、和值,检查类型是否可以具有这些插槽
- 如果基类尚未定义插槽(
base->tp\u dictoffset
为0),则只能有一个\u dict\u
插槽
- 如果基类型未定义插槽(
base->tp\u weaklistoffset
为0),并且基具有固定长度的实例(base->tp\u itemsize
为0),则只能拥有\uuuuuuuukref\uuuuuu
插槽
- 然后,如果没有
\uuuuuuuuuuuuuuu插槽
,则设置标志变量以实际启用要添加的插槽
代码很长,但相关部分如下所示:
slots=\u PyDict\u getitemidwerstror(dict,&PyId\uuuuu slots);
nslots=0;
加上_dict=0;
加上_弱=0;
may\u add\u dict=base->tp\u dict offset==0;
可以添加\u weak=base->tp\u weaklistoffset==0&&base->tp\u itemsize==0;
如果(插槽==NULL){
如果(Pyrr_发生()){
转到错误;
}
如果(可以添加命令){
添加_dict++;
}
如果(可以加上弱){
添加_弱++;
}
}
否则{
/*有空位*/
...
}
然后,向下大约400行,您将找到实际创建插槽的代码:
if(添加命令){
if(基本->tp\U项目大小)
类型->tp_dictoffset=-(长)sizeof(PyObject*);
其他的
类型->tp\u dictoffset=slotofset;
slotofset+=sizeof(PyObject*);
}
如果(添加弱){
断言(!base->tp_itemsize);
类型->tp_weaklistoffset=slotofset;
slotofset+=sizeof(PyObject*);
}
当扩展某些本机类型(例如int
或bytes
)时,您不会得到\uuuuuwakref\uuuwakref
插槽,因为它们具有可变长度的实例(由tp\uitemsize
处理)。非常感谢。“对于Python类,情况总是如此”,除了可变长度类型的子类(如内置类型int
、tuple
、和字节
),因为它们具有非零\uuuuuuuuitemsize\uuuuuuuuuuuuuuuuuu
属性,因此它们将不会获得\uuuuuuuuuuwweakref\uuuuuuuucode>属性,对吗?@Maggyero-right,这取决于底座的类型。我应该说得更清楚,编辑得不错。关于术语,当我们说“插槽”时,是指类上的描述符还是描述符引用的每个类实例上的保留存储,还是两者都是?@Maggyero是保留存储。描述符是内存和Python代码之间的桥梁