python类型中的__flags__用于什么

时间:2017-12-04 12:34:34

标签: python python-2.7 pickle cpython

我最近读过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__

任何人都可以帮我解决这个难题吗?

2 个答案:

答案 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