Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
166 views
in Technique[技术] by (71.8m points)

python - Py_INCREF/DECREF: When

Is one correct in stating the following:

  1. If a Python object is created in a C function, but the function doesn't return it, no INCREF is needed, but a DECREF is.

  2. [false]If the function does return it, you do need to INCREF, in the function that receives the return value.[/false]

  3. When assigning C typed variables as attributes, like double, int etc., to the Python object, no INCREF or DECREF is needed.

  4. Is the following safe to use? Assigning Python objects as attributes to your other Python objects goes like this:

    PyObject *foo;
    foo = bar;  // A Python object
    tmp = self->foo;
    Py_INCREF(foo);
    self->foo = foo;
    Py_XDECREF(tmp);
    // taken from the manual, but it is unclear if this works in every situation
    
  5. Deallocation of a Python object needs to DECREF for every other Python object that it has as an attribute, but not for attributes that are C types.


EDIT:

With regards to 'C type as an attribute', I mean bar and baz:

typedef struct {
    PyObject_HEAD
    PyObject *foo;
    int bar;
    double baz;
} FooBarBaz;
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

First, read this more carefully, specifically the last paragraph, http://docs.python.org/extending/extending.html#ownership-rules

Easy way to think about it is thinking about the reference counts.

  1. Your first statement is correct. If you create a new Python object (say PyLong) then it already has a reference count of 1. This is fine if you're going to return it but if you're not going to return it, it needs to be garbage collected by Python and it is only marked for GC with refcount=0, thus you need to DECREF if you're not going to return it.

  2. The second statement is false. If you need to return it and you created it, just return it. Returning transfers ownership. If you were to INCREF before returning, then you're telling Python that you also are retaining a copy. So again, if you create it, refcount=1. If you then do INCREF then refcount=2. But this is not what you want, you want to return with refcount=1.

  3. I'm not quite sure I get this but this is more of a C related question. How are you adding an int or double to a Python object?

  4. Can you give an example where that method won't work?

  5. Again, I'm not sure when a C type is an attribute of a Python object. Every int, double, long, etc. is wrapped by a Python object in some way or another.

The caveats to these answers are outlined in the link above. You really shouldn't even need my poor explanation after reading that. I hope I clarified and didn't confuse more.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...