8
  • __dict__如果在 Python 中定义了一个“普通”类,它是如何创建的?
  • 是否有任何带有 s 的非动态类型的示例__dict__
  • 通过 Python 定义的类型是否PyTypeObject通过type_new

有一个tp_dict成员PyTypeObject,但我找不到有关如何使用它的信息。typeobject.c's中似乎也发生了一些事情,type_new但我无法清楚地破译它。

以下是我找到的一些相关信息:

4

4 回答 4

6

以下代码将生成一个__dict__在 Python 2.x 中实现 a 的类:

typedef struct {
  PyObject_HEAD
  PyObject* dict;
} BarObject;

static PyTypeObject BarObject_Type = {
  PyObject_HEAD_INIT(NULL)
};

PyMODINIT_FUNC
initFoo(void)
{
  PyObject *m;

  m = Py_InitModule("Foo", NULL);
  if (m == NULL)
    return;

  BarObject_Type.tp_new = PyType_GenericNew;
  BarObject_Type.tp_name = "Foo.Bar";
  BarObject_Type.tp_basicsize = sizeof(BarObject);
  BarObject_Type.tp_getattro = PyObject_GenericGetAttr;
  BarObject_Type.tp_setattro = PyObject_GenericSetAttr;
  BarObject_Type.tp_flags = Py_TPFLAGS_DEFAULT;
  BarObject_Type.tp_dictoffset = offsetof(BarObject,dict);
  BarObject_Type.tp_doc = "Doc string for class Bar in module Foo.";
  if (PyType_Ready(&BarObject_Type) < 0)
    return;

  Py_INCREF(&BarObject_Type);
  PyModule_AddObject(m, "Bar", (PyObject*)&BarObject_Type);
}

重要的是结构的tp_dictoffset成员PyTypeObjecthttp://docs.python.org/c-api/typeobj.html):

如果这个类型的实例有一个包含实例变量的字典,这个字段是非零的并且包含实例变量字典的类型的实例中的偏移量;PyObject_GenericGetAttr() 使用这个偏移量。

不要将此字段与 tp_dict 混淆;那是类型对象本身属性的字典。

于 2012-09-20T02:31:45.917 回答
2

首先回答最后一个问题:不,type_new仅用于在运行时动态定义的“堆类型”(例如通过类语句)。PyType_Ready()相反,静态定义的类型被初始化。

要回答您的第一个问题:要使用描述符创建扩展类型__dict__,您需要像解释器为类定义所做的那样动态分配类型。

获取示例的一种方法是按照 John 的建议进行操作,并使用 Cython 生成一些您自己的示例。

对于 CPython 2.x,您可以查看build_classCPython 源代码 ( http://svn.python.org/view/python/trunk/Python/ceval.c?view=markup ) 中的方法以了解步骤涉及一个完全通用的解决方案。

如果您使用的是 Python 3,那么这个问题可能会引起您的兴趣:Python 的内置 __build_class__ 是做什么的?

也就是说,作为 CPython 3.x 特定的解决方案,最简单的方法是builtins.__build_class__通过 C API 使用适当的参数进行调用。

于 2011-02-21T01:58:06.650 回答
1

我还没有这样做,我在使用 C-API 时非常糟糕,但根据文档,使用andPyObject_GenericGetAttr方法应该就足够PyObject_GenericSetAttr了。当然,您还需要有一个 PyObject 属性。getattrosetattro__dict__

你试过吗?

于 2011-02-21T09:47:12.593 回答
0

编写一些定义一个类和一个或两个方法的 Python 代码,用 Cython 编译它并检查生成的 C 代码怎么样?

于 2011-02-21T00:53:45.920 回答