6

I have a C++ program, I want to import a Python module and list all function names in this module. How can I do it?

I used the following code to get the dict from a module:

PyDictObject* pDict = (PyDictObject*)PyModule_GetDict(pModule);

But how to list the functions names?

1
  • thanks for your reply , actually my requests is import a python module into C++ and get all function names and filled them to a combobox that i can select which function to be executed , and i am not familiar with python CAPI , so i don't know how to extract function names , i found PyModule_GetDict function but don't know how to iterate over it Commented Sep 25, 2019 at 11:16

1 Answer 1

6

Out of curiosity, I tried to puzzle this out.

First, a minimal Python module testModule.py:

def main():
  print("in test.main()")

def funcTest():
  print("in test.funcTest()")

Second, a minimal C++ sample testPyModule.cc to load and evaluate the testModule:

// standard C++ header:
#include <iostream>

// Python header:
#include <Python.h>

int main()
{
  // initialize Python interpreter
  Py_Initialize();
  // run script
  const char *const script =
    "# tweak sys path to make Python module of cwd locatable\n"
    "import sys\n"
    "sys.path.insert(0, \".\")\n";
  PyRun_SimpleString(script);
  // get module testModule
  PyObject *pModuleTest = PyImport_ImportModule("testModule"); // new reference
  // evaluate dictionary of testModule
  PyObject *const pDict = PyModule_GetDict(pModuleTest); // borrowed
  // find functions
  std::cout << "Functions of testModule:\n";
  PyObject *pKey = nullptr, *pValue = nullptr;
  for (Py_ssize_t i = 0; PyDict_Next(pDict, &i, &pKey, &pValue);) {
    const char *key = PyUnicode_AsUTF8(pKey);
    if (PyFunction_Check(pValue)) {
      std::cout << "function '" << key << "'\n";
    }
  }
  Py_DECREF(pModuleTest);
  // finalize Python interpreter
  Py_Finalize();
}

Output:

Functions of testModule:
function 'main'
function 'funcTest'

Notes:

To puzzle this out, I had to dig through the doc. pages. These are the links for the pages I used:

It's obvious that I didn't check any pointer for NULL (or nullptr) to keep the sample short and compact. Production code should do this, of course.

Sign up to request clarification or add additional context in comments.

3 Comments

thanks very much , i learn much from your code , that's helpful , really appreciated
Even aside from error checking, this is highly non-idiomatic. What happened to PyImport_ImportModule and PyDict_Next?
@DavisHerring May be, I didn't dig hard enough. I made and checked a revised sample according to your hints. Thanks for the comment.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.