Расширенные примеры использования F2PY
Добавление функций, написанных пользователем, в модули, сгенерированные F2PY
Функции Python C/API, написанные пользователем, могут быть определены внутри файлов сигнатур с использованием инструкций usercode и pymethoddef (они должны использоваться внутри блока python module). Например, следующий файл сигнатур spam.pyf
! -*- f90 -*-
python module spam
usercode '''
static char doc_spam_system[] = "Execute a shell command.";
static PyObject *spam_system(PyObject *self, PyObject *args)
{
char *command;
int sts;
if (!PyArg_ParseTuple(args, "s", &command))
return NULL;
sts = system(command);
return Py_BuildValue("i", sts);
}
'''
pymethoddef '''
{"system", spam_system, METH_VARARGS, doc_spam_system},
'''
end python module spam
оборачивает функцию C-библиотеки system()
f2py -c spam.pyf
В Python:
>>> import spam
>>> status = spam.system('whoami')
pearu
>>> status = spam.system('blah')
sh: line 1: blah: command not found
Модификация словаря сгенерированного F2PY модуля
Следующий пример демонстрирует, как добавить пользовательские переменные в сгенерированный F2PY модуль расширения. Дано следующий файл сигнатур
! -*- f90 -*-
python module var
usercode '''
int BAR = 5;
'''
interface
usercode '''
PyDict_SetItemString(d,"BAR",PyInt_FromLong(BAR));
'''
end interface
end python module
скомпилируйте его как f2py -c var.pyf
Обратите внимание, что вторая инструкция usercode должна быть определена внутри блока interface и где словарь модуля доступен через переменную d (см. f2py var.pyf-сгенерированный varmodule.c для дополнительных подробностей).
В Python:
>>> import var >>> var.BAR 5
Работа со спецификаторами KIND
В настоящее время F2PY может обрабатывать только объявления <type spec>(kind=<kindselector>), где <kindselector> является целочисленным числом (например, 1, 2, 4,…), но не вызов функции KIND(..) или любое другое выражение. F2PY необходимо знать, какой будет соответствующий тип C, и общее решение для этого было бы слишком сложным для реализации.
Однако, F2PY предоставляет возможность обойти эту трудность, а именно, пользователи могут определить свои собственные соответствия между типами Fortran и типами C. Например, если код Fortran 90 содержит:
REAL(kind=KIND(0.0D0)) ...
тогда создайте файл сопоставления, содержащий словарь Python:
{'real': {'KIND(0.0D0)': 'double'}}
например.
Используйте опцию командной строки --f2cmap для передачи имени файла F2PY. По умолчанию F2PY предполагает, что имя файла .f2py_f2cmap в текущем рабочем каталоге.
Или более общим образом, файл f2cmap должен содержать словарь со следующими элементами:
<Fortran typespec> : {<selector_expr>:<C type>}
что определяет сопоставление между типом Fortran:
<Fortran typespec>([kind=]<selector_expr>)
и соответствующим типом C. Тип C может быть одним из следующих:
char signed_char short int long_long float double long_double complex_float complex_double complex_long_double string
Для получения дополнительной информации см. исходный код F2Py numpy/f2py/capi_maps.py
© 2005–2022 NumPy Developers
Licensed under the 3-clause BSD License.
https://numpy.org/doc/1.21/f2py/advanced.html