Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a Python function taking *args/**kwargs be called from C or another language space?

Tags:

python

c

Take a canonical Python function defined like:

def foo(*args, **kwargs):
  print("args:", len(args))
  for i in args:
    print(i)

  print("kwargs:", len(kwargs))
  for k in kwargs:
    print(k, kwargs[k])

Calling this function from Python might look like:

some_list = ['one', 'two', 'three']
some_kwords = { "name1" : "alice", "name2" : "bob", "name3" : "carol" }

foo(*some_list, **some_kwords)

Does the Python C API provide some way to call this function from C space? How can the above three lines be converted to C equivalent?

Note that in a similar question, using boost::python, C++ calls into this keyword argument function with almost the same syntax as from Python, which is quite a trick!

like image 410
greatwolf Avatar asked Jan 17 '13 03:01

greatwolf


People also ask

Can you index args in Python?

You can extract arguments based on index like we get a value from tuple based on index position args[0] refers to first argument as indexing in python starts from zero. How to use args in loop? You can access arguments in loop by running it over args tuple.

How does Python Kwargs work?

**kwargs works just like *args , but instead of accepting positional arguments it accepts keyword (or named) arguments. Take the following example: # concatenate.py def concatenate(**kwargs): result = "" # Iterating over the Python kwargs dictionary for arg in kwargs.

What is the correct way to use the Kwargs statement?

The double asterisk form of **kwargs is used to pass a keyworded, variable-length argument dictionary to a function. Again, the two asterisks ( ** ) are the important element here, as the word kwargs is conventionally used, though not enforced by the language.

How do you pass an argument to a function in Python?

Information can be passed into functions as arguments. Arguments are specified after the function name, inside the parentheses. You can add as many arguments as you want, just separate them with a comma.


1 Answers

To call a function with arbitrary positional and keyword arguments in Python/C, equivalent to the function(*args, **kwds) syntax, use PyObject_Call:

/* error checking omitted for brevity */
PyObject *some_list = PyObject_BuildValue("(sss)", "one", "two", "three");
PyObject *some_kwords = PyObject_BuildValue("{s:s,s:s,s:s}",
                          "name1", "alice", "name2", "bob", "name3", "carol");
PyObject *ret = PyObject_Call(foo, some_list, some_kwords);
Py_DECREF(some_list);
Py_DECREF(some_kwords);
like image 81
user4815162342 Avatar answered Sep 29 '22 00:09

user4815162342