Spec-Zone.ru › NumPy 1.20

Расширенные примеры использования 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–2021 NumPy Developers
Licensed under the 3-clause BSD License.
https://numpy.org/doc/1.20/f2py/advanced.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API