1

So, the python docs for writing extension says this:

"We want to expose our instance variables as attributes. There are a number of ways to do that. The simplest way is to define member definitions:

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 */
};

and put the definitions in the tp_members slot:

Noddy_members,             /* tp_members */"

However, we have already put the instance variables in the Noddy struct:

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

so my question is that why we put them in both places. My impression is that, that is because we want both type and the instance to have them so that we preserve the types values once the instance get updated. But If thats the case, how does the instance value get updated if we change the class attribute? like this:

>>> class foo(object): x = 4
...
>>> f = foo()
>>> f.x
4
>>> foo.x = 5
>>> f.x
5
theRealWorld
  • 1,188
  • 2
  • 8
  • 23

2 Answers2

3

Writing a C extension is a complex process, because you have to write C code, and you have to provide enough information to Python so that it can manipulate your C data as if it were Python data. You have to mention the members of the struct twice: once for the C compiler to know how to make the struct, and then again so that Python knows where the data is, and what it is called.

C has no introspection ability, so you can't (for example), get a list of members of a struct at runtime. The array of PyMemberDef provides that information.

Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662
  • 2
    Another way to put it is, Python has no ability to look into your C source code and see the names and types of the members of your `struct`. That information ordinarily does not even exist in compiled code, so you have to put it there for Python to have access to it. – kindall Jun 30 '11 at 19:52
1

Ok So I did my research and yes instance variables and attributes are different and thats because classes instances and classes have separate dictionaries. As said in the documentation::

A class instance is created by calling a class object (see above). A class instance has a namespace implemented as a dictionary which is the first place in which attribute references are searched. When an attribute is not found there, and the instance’s class has an attribute by that name, the search continues with the class attributes.

So basically the Noddy struct holds the instance variables. The Noddy_members holds the attributes. Furthermore:

Attribute assignments and deletions update the instance’s dictionary, never a class’s dictionary. If the class has a setattr() or delattr() method, this is called instead of updating the instance dictionary directly.

Also:

If a class attribute is found that is a user-defined function object or an unbound user-defined method object whose associated class is the class (call it C) of the instance for which the attribute reference was initiated or one of its bases, it is transformed into a bound user-defined method object whose im_class attribute is C and whose im_self attribute is the instance. Static method and class method objects are also transformed, as if they had been retrieved from class C; see above under “Classes”. See section Implementing Descriptors for another way in which attributes of a class retrieved via its instances may differ from the objects actually stored in the class’s dict. If no class attribute is found, and the object’s class has a getattr() method, that is called to satisfy the lookup.

theRealWorld
  • 1,188
  • 2
  • 8
  • 23