Py_INCREF/DECREF: When

2024/11/19 11:19:14

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_HEADPyObject *foo;int bar;double baz;
} FooBarBaz;
Answer

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.

https://en.xdnf.cn/q/26440.html

Related Q&A

pop/remove items out of a python tuple

I am not sure if I can make myself clear but will try.I have a tuple in python which I go through as follows (see code below). While going through it, I maintain a counter (lets call it n) and pop item…

Difference between frompyfunc and vectorize in numpy

What is the difference between vectorize and frompyfunc in numpy?Both seem very similar. What is a typical use case for each of them?Edit: As JoshAdel indicates, the class vectorize seems to be built…

Jupyter notebook command does not work on Mac

I installed jupyter using pip on my macbook air. Upon trying to execute the command jupyter notebook, I get an error jupyter: notebook is not a Jupyter commandI used the --h option to get a listing of …

Recursively compare two directories to ensure they have the same files and subdirectories

From what I observe filecmp.dircmp is recursive, but inadequate for my needs, at least in py2. I want to compare two directories and all their contained files. Does this exist, or do I need to build …

Specific reasons to favor pip vs. conda when installing Python packages

I use miniconda as my default python installation. What is the current (2019) wisdom regarding when to install something with conda vs. pip?My usual behavior is to install everything with pip, and onl…

Insert a link inside a Pandas table

Id like to insert a link (to a web page) inside a Pandas table, so when it is displayed in an IPython notebook, I could press the link. I tried the following: In [1]: import pandas as pdIn [2]: df = pd…

TypeError: string indices must be integers while parsing JSON using Python?

I am confuse now why I am not able to parse this JSON string. Similar code works fine on other JSON string but not on this one - I am trying to parse JSON String and extract script from the JSON.Below …

Python dynamic inheritance: How to choose base class upon instance creation?

IntroductionI have encountered an interesting case in my programming job that requires me to implement a mechanism of dynamic class inheritance in python. What I mean when using the term "dynamic …

Python: efficiently check if integer is within *many* ranges

I am working on a postage application which is required to check an integer postcode against a number of postcode ranges, and return a different code based on which range the postcode matches against.E…

How to pass on argparse argument to function as kwargs?

I have a class defined as followsclass M(object):def __init__(self, **kwargs):...do_somethingand I have the result of argparse.parse_args(), for example:> args = parse_args() > print args Namespa…