Я большой сторонник того, чтобы в Python происходило как можно больше работы, оставляя только ту работу, которая должна происходить в C в C. Так что мне нравится № 2 лучше, чем # 1, но вы правы, это беспорядок все подписи вашей функции.
Я бы создал объект уровня модуля для обработки журналов, что-то вроде обратного вызова. Код Python может создать объект любым удобным для него способом, а затем назначить его объекту модуля. Код C может просто использовать глобальный объект для ведения своей регистрации:
# Python:
import my_compiled_module
def log_it(level, msg):
print "%s: Oh, look: %s" % (level, msg)
my_compiled_module.logger = log_it
# C
static void log_it(unsigned int level, char * msg)
{
PyObject * args = Py_BuildValue("(Is)", level, msg);
PyObject_Call(log_it, args, NULL);
Py_DECREF(args);
}
Теперь вы можете просто вызывать функцию C log_it по всему коду и не беспокоиться о том, как это делает код Python. Конечно, ваша функция Python log_it будет богаче, чем эта, и она позволит вам объединить все ваши записи в один Python logger.