高级f2py用法

向f2py生成的模块添加自写函数

自写的python c/api函数可以在签名文件中使用 usercodepymethoddef 语句(它们必须在 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

处理种类说明符

目前,F2PY只能处理 <type spec>(kind=<kindselector>) 声明,其中 <kindselector> 是一个数字整数(例如1,2,4,…),但不是函数调用 KIND(..) 或者其他任何表情。F2PY需要知道什么是对应的C类型,并且一个通用的解决方案太复杂而无法实现。

然而,F2PY提供了一个钩子来克服这个困难,即用户可以定义自己的<Fortran type>到<C type>映射。例如,如果Fortran 90代码包含:

REAL(kind=KIND(0.0D0)) ...

然后创建一个包含Python字典的映射文件:

{'real': {'KIND(0.0D0)': 'double'}}

例如。

使用 --f2cmap 将选项传递给命令行。默认情况下,F2PY假定文件名为 .f2py_f2cmap 在当前工作目录中。

或者更一般地说,f2cmap文件必须包含一个包含以下项的字典:

<Fortran typespec> : {<selector_expr>:<C type>}

定义Fortran类型之间的映射:

<Fortran typespec>([kind=]<selector_expr>)

以及相应的<C类型>。<C type>可以是以下类型之一:

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 .