我正在尝试使用 h5py 模块将一组深度嵌套的类、属性、绑定方法等写入 HDF5 文件以进行长期存储。我真的很接近。我似乎无法解决的唯一问题是在运行时以编程方式找出一种方法来确定某物是否是类实例类型,而不是列表、int 等。我需要递归到类实例,但显然不应该递归为 int、float 等。这需要适用于旧式和新式类。我研究过的东西不起作用/我无法开始工作:
使用检查模块
>>> class R(object): pass
...
>>> _R = R()
>>> import inspect
>>> inspect.isclass(_R)
False
>>> inspect.isclass(R)
True
这没有帮助,我需要一个像inspect.isclassinstance(_R)
回来True
使用类型模块
如果您使用旧式类,则有一种名为 InstanceType 的类型可以匹配旧式类的实例,如下面的代码所示
>>> import types
>>> class R(): pass #old-style class
...
>>> _R = R()
>>> import types
>>> type(_R) is types.InstanceType
True
>>> class R(object): pass #new-style class
...
>>> _R = R()
>>> type(_R) is types.InstanceType
False
但是如果你使用新式类则没有对应的类型types
虽然发帖者很可能需要重新考虑他的设计,但在某些情况下,确实需要区分用 C 创建的内置/扩展类型的实例和用 Python 创建的类的实例class
陈述。虽然两者都是类型,但后者是 CPython 内部称为“堆类型”的类型类别,因为它们的类型结构是在运行时分配的。 python继续区分它们可以在__repr__
output:
>>> int # "type"
<type 'int'>
>>> class X(object): pass
...
>>> X # "class"
<class '__main__.X'>
The __repr__
区分是通过检查类型是否是堆类型来实现的。
根据应用程序的具体需求,is_class_instance
功能可以通过以下方式之一实现:
# Built-in types such as int or object do not have __dict__ by
# default. __dict__ is normally obtained by inheriting from a
# dictless type using the class statement. Checking for the
# existence of __dict__ is an indication of a class instance.
#
# Caveat: a built-in or extension type can still request instance
# dicts using tp_dictoffset, and a class can suppress it with
# __slots__.
def is_class_instance(o):
return hasattr(o, '__dict__')
# A reliable approach, but one that is also more dependent
# on the CPython implementation.
Py_TPFLAGS_HEAPTYPE = (1<<9) # Include/object.h
def is_class_instance(o):
return bool(type(o).__flags__ & Py_TPFLAGS_HEAPTYPE)
EDIT
这是该函数第二个版本的解释。它确实使用 CPython 内部出于其自身目的使用的相同测试来测试该类型是否为“堆类型”。这确保了它对于堆类型(“类”)的实例始终返回 True,对于非堆类型(“类型”,但也很容易修复的旧式类)实例始终返回 False。它通过检查是否tp_flags memberC级的PyTypeObject结构有Py_TPFLAGS_HEAPTYPE
位设置。该实现的薄弱部分是它硬编码了Py_TPFLAGS_HEAPTYPE
恒定为当前观察到的值。 (这是必要的,因为该常量不会通过符号名称暴露给 Python。)虽然理论上该常量可能会更改,但在实践中极不可能发生,因为这种更改会无缘无故地破坏现有扩展模块的 ABI。看着的定义Py_TPFLAGS常量 in Include/object.h
,很明显,新的内容正在被小心地添加,而不会干扰旧的内容。另一个弱点是此代码在非 CPython 实现(例如 Jython 或 IronPython)上运行的机会为零。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)