F2PY用户指南和参考手册 > F2PY的高级用法
可以使用usercode
和pymethoddef
语句在签名文件中定义自写的Python C / API函数(必须在块中使用它们)。例如,以下签名文件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生成的扩展模块中。给定以下签名文件
! -*- 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
(有关更多详细信息,请参见-genic )。f2py var.pyf
varmodule.c
在Python中:
>>> import var
>>> var.BAR
5
目前,F2PY只能处理
,其中声明是一个数值整数(例如,1,2,4,...),而不是函数调用或任何其他表达。F2PY需要知道什么是对应的C类型,并且通用的解决方案实施起来太复杂了。<type spec>(kind=<kindselector>)
<kindselector>
KIND(..)
但是,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 type>。<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
。