我最近读过pickle源代码。
copy_reg
中的以下代码让我感到困惑:
_HEAPTYPE = 1<<9
def _reduce_ex(self, proto):
assert proto < 2
for base in self.__class__.__mro__:
if hasattr(base, '__flags__') and not base.__flags__ & _HEAPTYPE:
break
else:
base = object # not really reachable
if base is object:
state = None
那么__flags__
用于什么?
我发现它在type
对象中定义:
type.__flags__ = 2148423147
我试图在官方文档中搜索它,但没有找到任何内容。
但有趣的是,当__class__.__flags__ & _HEAPTYPE
是python内部类型时,0
总是__class__
。当1
是python内部类型的子类时,结果将为__class__
。
任何人都可以帮我解决这个难题吗?
答案 0 :(得分:2)
__flags__
是一个包装器,to access CPython type object structure member tp_flags
,用于组成此标志defined in object.h的常量,以下是从源中引用的:
类型标志(tp_flags) 这些标志用于向后兼容扩展类型结构 时尚。扩展可以使用标志来指示(和测试)给定的时间 类型结构包含一个新功能。 Python核心将在何时使用它们 在主要修订版之间引入新功能(以避免中间版本 PYTHON_API_VERSION中的更改。
详情请见python document on tp_flags
。
但有趣的是类。标志&amp;当类是python内部类型时,_HEAPTYPE始终为0。当 class 是python内部类型的子类时,结果将为1。
与其他用户定义类型一样的python内置类型的子类,在PyType_GenericAlloc()
堆上分配。
分解type.__flags__
:
import re
def flags_to_name(type_obj):
tp_flag_consts = {}
with open('/path/to/Include/object.h') as f:
for l in f:
m = re.search(r'^#define (Py_TPFLAGS_\w+)\s+\(.+?<< (\d+)\)', l.strip())
if m:
tp_flag_consts[int(m.group(2))] = m.group(1)
bin_str = bin(type_obj.__flags__)[2:][::-1]
return ', '.join(tp_flag_consts[n] for n, c in enumerate(bin_str) if c == '1')
print(flags_to_name(type))
的产率:
Py_TPFLAGS_BASETYPE, Py_TPFLAGS_READY, Py_TPFLAGS_HAVE_GC, Py_TPFLAGS_HAVE_VERSION_TAG, Py_TPFLAGS_VALID_VERSION_TAG, Py_TPFLAGS_TYPE_SUBCLASS
答案 1 :(得分:1)
__flags__
将被视为二进制。
这些类型标志在Python的源代码中定义为here。