Obtaining global and local dict's for current interpreter using C API

Alex Martelli aleax at aleax.it
Wed Nov 6 05:52:16 EST 2002


quadric at primenet.com wrote:
   ...
> How , and using which C API functions, do you acquire the PyObject * to
> the dictionaries
> ( both local and global) of the current interpreter.  I AM NOT looking for
> the dictionary of an
> imported module, but rather the dictionary of the current interpreter. 

There is no "dictionary of the current interpreter".  Each module has
a dictionary (also known as its "global dictionary") and each execution
frame has a local dictionary (the local variables of a function that's
executing don't necessarily use a real dictionary -- as an optimization,
they're basically held as an array -- but that's a different issue).

> You know, the one
> you get when executing  'dir()'  in the interpreter window.

That's the dictionary of the module named __main__.  You can get at
the module as sys.modules['__main__'], and its dict is the __dict__
attribute of the module, of course:

[alex at lancelot trans]$ python2.2
Python 2.2.2 (#1, Oct 24 2002, 11:43:01)
[GCC 2.96 20000731 (Mandrake Linux 8.2 2.96-0.76mdk)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> vars() is sys.modules['__main__'].__dict__
1
>>> 

and dir() just gives the sorted keys of vars().

 
> The C API docs say to do the following:
> 
> PyObject * pdict = PyObject_Dir(NULL);
> 
> and , assuming an execution frame is active, should return the dictionary.
> 
> 1>    What is an execution frame?
> 2>    How do I know if an execution frame is active?
> 3>    I've tried this and only get NULL in return, indicating the absence of
> an active
> execution frame, I guess?

Basically, an execution frame is active if your code is being
called from Python code.  Some info on frame objects is towards
the end of http://www.python.org/doc/current/ref/types.html .


> My code looks similar to this:
> 
> PyObject * pres = NULL , * pdict = NULL;
> int  result = 0;
> 
> Py_Initialize();
> 
> pdict = PyObject_Dir(NULL);   // Returns a useless NULL pointer
> 
> if ( pdict != NULL )
> {
> PyRun_SimpleString( "result = 4 + 5" );
> pres = PyObject_GetAttrString( pdict , "result" );
> PyArg_Parse( pres , "i" , &result);
> }
> 
> 
> // decrement any references here
> 
> Py_Finalize();

This code also has other problems -- if you DID manage to get
the main module's directory, you would find that it does not
have an ATTRIBUTE named result, but rather an ITEM by that name
(key, actually).  Anyway, here's a roughly equivalent little
program, which however should work as I think you intend:

#include "Python.h"
#include <stdio.h>

int main(int argc, char **argv)
{
    PyObject *pres, *mainmodule;
    int  result = 0;

    Py_Initialize();
    mainmodule = PyImport_AddModule("__main__");
    PyRun_SimpleString("result = 4 + 5\n");
    pres = PyObject_GetAttrString(mainmodule, "result");

    PyArg_Parse(pres, "i", &result);
    Py_Finalize();

    printf("Result is %d\n", result);

    return 0;
}


Alex




More information about the Python-list mailing list