python中实例变量和属性之间的区别?

时间:2011-06-30 18:17:39

标签: python c cython python-c-api python-c-extension

因此,writing extension的python文档说明了这一点:

  

“我们希望公开我们的实例   变量作为属性。有一个   有多少方法可以做到这一点。该   最简单的方法是定义成员   定义:

static PyMemberDef Noddy_members[] = {
    {"first", T_OBJECT_EX, offsetof(Noddy, first), 0,
     "first name"},
    {"last", T_OBJECT_EX, offsetof(Noddy, last), 0,
     "last name"},
    {"number", T_INT, offsetof(Noddy, number), 0,
     "noddy number"},
    {NULL}  /* Sentinel */
};
     

并将定义放入   tp_members插槽:

Noddy_members,             /* tp_members */"

但是,我们已经将实例变量放在Noddy结构中了:

 typedef struct {
    PyObject_HEAD
    PyObject *first;
    PyObject *last;
    int number;
} Noddy;

所以我的问题是为什么我们把它们放在两个地方。我的印象是,这是因为我们希望类型和实例都有它们,以便在实例更新后保留类型值。但如果是这样的话,如果我们更改类属性,实例值如何更新?像这样:

>>> class foo(object): x = 4
...
>>> f = foo()
>>> f.x
4
>>> foo.x = 5
>>> f.x
5

2 个答案:

答案 0 :(得分:2)

编写C扩展是一个复杂的过程,因为您必须编写C代码,并且必须向Python提供足够的信息,以便它可以像处理Python数据那样操作C数据。你必须两次提到结构的成员:一次是让C编译器知道如何制作结构,然后再一次让Python知道数据的位置,以及它的名称。

C没有内省能力,所以你不能(例如)在运行时获取结构的成员列表。 PyMemberDef数组提供了这些信息。

答案 1 :(得分:1)

好的所以我做了我的研究,是的实例变量和属性是不同的,因为类实例和类有单独的字典。如documentation ::

中所述
  

通过调用创建类实例   一个类对象(见上文)。一类   instance实现了一个名称空间   作为第一个字典   属性引用的位置   被搜查。当属性不是   发现那里,以及实例的类   有一个该名称的属性,   继续搜索课程   属性。

所以基本上Noddy结构包含实例变量。 Noddy_members拥有属性。此外:

  

属性分配和删除   更新实例的字典,   从来没有班级的字典。如果   class有 setattr ()或    delattr ()方法,调用此方法而不是更新实例   字典直接。

此外:

  

如果找到的是class属性   用户定义的函数对象或   未绑定的用户定义方法对象   其关联的类是类   (称之为C)的实例   属性引用已启动   或其中一个基地,它被改造   到用户定义的绑定方法   im_class属性为C的对象   并且其im_self属性是   实例。静态方法和类   方法对象也被转换,   好像他们是从那里取回来的   C级;见上文“课程”。   请参阅实现描述符部分   另一种方式,其中的属性   通过其实例检索的类   可能与实际的对象不同   存储在班级的 dict 中。如果不   找到class属性,然后   object的类有一个 getattr ()   方法,被称为满足   查找。