F2PY用户指南和参考手册 > 签名文件
签名文件(.pyf文件)的语法规范是从Fortran 90/95语言规范中借用的。自由和固定格式都可以理解几乎所有的Fortran 90/95标准构造(请记住,Fortran 77是Fortran 90/95的子集)。F2PY还引入了对Fortran 90/95语言规范的一些扩展,这些扩展有助于设计从Fortran到Python的接口,使其更加“ Pythonic”。
签名文件可以包含任意的Fortran代码(以便可以将Fortran代码视为签名文件)。F2PY默默地忽略了与创建接口无关的Fortran构造。但是,这也包括语法错误。因此,请小心不要制造;-)。
通常,签名文件的内容区分大小写。扫描Fortran代码并写入签名文件时,F2PY会自动降低所有情况,除非在多行块中或使用--no-lower
选项时。
签名文件的语法如下所示。
签名文件可能包含一个(推荐)或多个块。 块描述了F2PY生成的Python / C扩展模块的内容。python
module
python module
<modulename>module.c
例外:如果<modulename>
包含一个substring __user__
,则相应的块描述了所谓的回调函数的签名(请参阅回调参数)。python module
阿块具有以下结构:python module
python module <modulename>
[<usercode statement>]...
[
interface
<usercode statement>
<Fortran block data signatures>
<Fortran/C routine signatures>
end [interface]
]...
[
interface
module <F90 modulename>
[<F90 module data type declarations>]
[<F90 module routine signatures>]
end [module [<F90 modulename>]]
end [interface]
]...
end [python module [<modulename>]]
此处的括号[]
表示可选部分,点...
表示先前的一个或多个部分。因此,[]...
读取零个或多个先前的部分。
Fortran例程的签名具有以下结构:
[<typespec>] function | subroutine <routine name> \
[ ( [<arguments>] ) ] [ result ( <entityname> ) ]
[<argument/variable type declarations>]
[<argument/variable attribute statements>]
[<use statements>]
[<common block statements>]
[<other statements>]
end [ function | subroutine [<routine name>] ]
F2PY从Fortran例程签名中生成具有以下签名的Python / C扩展函数:
def <routine name>(<required arguments>[,<optional arguments>]):
...
return <return variables>
Fortran块数据的签名具有以下结构:
block data [ <block data name> ]
[<variable type declarations>]
[<variable attribute statements>]
[<use statements>]
[<common block statements>]
[<include statements>]
end [ block data [<block data name>] ]
该部分的定义是<argument/variable type declaration>
<typespec> [ [<attrspec>] :: ] <entitydecl>
哪里
<typespec> := byte | character [<charselector>]
| complex [<kindselector>] | real [<kindselector>]
| double complex | double precision
| integer [<kindselector>] | logical [<kindselector>]
<charselector> := * <charlen>
| ( [len=] <len> [ , [kind=] <kind>] )
| ( kind= <kind> [ , len= <len> ] )
<kindselector> := * <intlen> | ( [kind=] <kind> )
<entitydecl> := <name> [ [ * <charlen> ] [ ( <arrayspec> ) ]
| [ ( <arrayspec> ) ] * <charlen> ]
| [ / <init_expr> / | = <init_expr> ] \
[ , <entitydecl> ]
和
<attrspec>
是用逗号分隔的属性列表;
<arrayspec>
是用逗号分隔的尺寸范围列表;
<init_expr>
是一个C表达式。
<intlen>
对于integer
类型规范,可以为负整数。在这种情况下,integer*<negintlen>
表示无符号的C整数。
如果参数没有,则通过将规则应用于名称来确定其类型。<argument type declaration>
implicit
该是
没有。另外,在一个属性语句中,一个人不能使用其他属性,也只能是一个名称列表。<argument/variable attribute statement>
<argument/variable type declaration>
<typespec>
<entitydecl>
该部分的定义是<use statement>
use <modulename> [ , <rename_list> | , ONLY : <only_list> ]
哪里
<rename_list> := <local_name> => <use_name> [ , <rename_list> ]
当前,F2PY use
仅将语句用于链接回调模块和external
参数(回调函数),请参阅
回调参数。
该部分的定义是<common block statement>
common / <common name> / <shortentitydecl>
哪里
<shortentitydecl> := <name> [ ( <arrayspec> ) ] [ , <shortentitydecl> ]
如果一个块包含两个或两个以上具有相同名称的块,则会附加附加声明中的变量。中的变量类型使用定义。注意,对应的可能包含数组规范;那么您无需在中指定这些
。python module
common
<shortentitydecl>
<argument type declarations>
<argument type declarations>
<shortentitydecl>
该部分引用了上面未描述的任何其他Fortran语言构造。F2PY会忽略其中的大多数,除了<other statement>
call
语句和external
参数的函数调用(更多详细信息?);
include
陈述include '<filename>'
include "<filename>"
如果文件<filename>
不存在,include
则忽略该语句。否则,该文件<filename>
将包含在签名文件中。 include
语句可以在签名文件的任何部分中使用,也可以在Fortran / C例程签名块之外使用。
implicit
陈述implicit none
implicit <list of implicit maps>
哪里
<implicit map> := <typespec> ( <list of letters or range of letters> )
如果未使用定义隐式规则,则使用隐式规则来确定变量的类型说明(从其名称的第一个字母开始)。默认的隐式规则由<variable type declaration>
implicit real (a-h,o-z,$_), integer (i-m)
entry
陈述entry <entry name> [([<arguments>])]
F2PY使用例程块的签名为所有条目名称生成包装器。
提示:entry
语句可用于描述任意例程的签名,从而允许F2PY仅从一个例程块签名生成许多包装器。这样做的限制很少:fortranname
不能使用,
callstatement
并且callprotoargument
仅当它们对所有输入例程均有效时才可以使用,等等。
此外,F2PY引入以下语句:
threadsafe
在对Fortran / C函数的调用周围使用块。Py_BEGIN_ALLOW_THREADS .. Py_END_ALLOW_THREADS
callstatement <C-expr|multi-line block>
将F2PY生成的对Fortran / C函数的调用语句替换为
。打包的Fortran / C函数可作为使用。要引发异常,请在中设置
。<C-expr|multi-line block>
(*f2py_func)
f2py_success = 0
<C-expr|multi-line block>
callprotoargument <C-typespecs>
当callstatement
使用statement时,F2PY可能不会为Fortran / C函数生成正确的原型(因为
<C-expr>
可能包含任何函数调用,并且F2PY无法确定什么才是正确的原型)。使用此语句,您可以显式指定相应原型的参数:
extern <return type> FUNC_F(<routine name>,<ROUTINE NAME>)(<callprotoargument>);
fortranname [<actual Fortran/C routine name>]
您可以对给定的Fortran / C函数使用任意函数。然后,您必须使用此语句指定
。<routine name>
<actual Fortran/C routine name>
如果fortranname
不使用该语句,
则将生成一个虚拟包装器。<actual Fortran/C routine name>
usercode <multi-line block>
在块内部使用时,给定的C代码将在包装函数定义之前插入到生成的C / API源中。例如,您可以在此处定义用于可选参数初始化的任意C函数。如果在块内部两次使用,则在定义外部例程之后插入第二个多行块。python module
usercode
python
module
当在内部使用时,给定的C代码将在声明变量之后但在任何C语句之前插入到相应的包装函数中。因此,
后续操作可以同时包含声明和C语句。<routine signature>
usercode
在第一个程序interface
块中使用时,将在扩展模块的初始化功能的末尾插入给定的C代码。在这里您可以修改扩展模块字典。例如,用于定义其他变量等。
pymethoddef <multiline block>
将在模块方法PyMethodDef
-array 的定义中插入多行块。它必须是C数组的逗号分隔列表(
有关详细信息,请参见扩展和嵌入 Python文档)。
pymethoddef
语句只能在块内部使用
。python module
F2PY使用以下属性:
optional
相应的参数将移动到列表的末尾。可以指定可选参数的默认值,请参见定义。请注意,默认值必须作为有效的C表达式给出。<optional
arguments>
<init_expr>
entitydecl
请注意,无论何时<init_expr>
使用,optional
F2PY都会自动设置属性。
对于可选的数组参数,必须限制其所有尺寸。
required
相应的参数被认为是必需的。这是默认值。required
仅optional
在<init_expr>
使用时需要禁用自动设置时才需要指定。
如果将Python None
对象用作必需参数,则该参数被视为可选参数。也就是说,在使用数组参数的情况下,将分配内存。如果<init_expr>
给出,则执行相应的初始化。
dimension(<arrayspec>)
对应的变量被视为中具有给定尺寸的数组<arrayspec>
。
intent(<intentspec>)
这指定了相应参数的“意图”。<intentspec>
是以下键的逗号分隔列表:
in
该自变量被视为仅输入自变量。这意味着参数的值将传递给Fortran / C函数,并且该函数不应更改参数的值。
inout
该自变量被视为输入/输出或原位
输出自变量。intent(inout)
参数只能是具有适当类型和大小的“连续” NumPy数组。这里的“连续”可以是Fortran或C形式。后者与NumPy中使用的连续概念相吻合,并且仅在intent(c)
使用时才有效。默认情况下,假定Fortran连续性。
使用intent(inout)
一般不推荐使用
intent(in,out)
来代替。另请参阅intent(inplace)
属性。
inplace
该自变量被视为输入/输出或原位
输出自变量。intent(inplace)
参数必须是具有适当大小的NumPy数组。如果数组的类型不正确,或者数组不连续,则将就地更改数组以修复该类型并使其连续。
使用intent(inplace)
一般不建议两种。例如,当从intent(inplace)
参数中获取切片
后,就地更改后,切片数据指针可能指向未分配的存储区。
out
该参数被视为返回变量。它被追加到列表中。自动使用
集,除非也使用
或。<returned variables>
intent(out)
intent(hide)
intent(in)
intent(inout)
默认情况下,返回的多维数组是Fortran连续的。如果intent(c)
使用,则返回的多维数组是C连续的。
hide
该参数将从必需或可选参数列表中删除。通常intent(hide)
与intent(out)
或<init_expr>
完全确定参数的值一起使用,如以下示例所示:
integer intent(hide),depend(a) :: n = len(a)
real intent(in),dimension(n) :: a
c
该参数被视为C标量或C数组参数。对于标量参数,其值作为C标量参数传递给C函数(请注意,Fortran标量参数实际上是C指针参数)。对于数组参数,假定包装函数将多维数组视为C连续数组。
intent(c)
无论包装函数是Fortran还是C函数,都无需使用一维数组。这是因为Fortran和C连续性的概念在一维情况下重叠。
如果intent(c)
用作语句但没有实体声明列表,则F2PY将intent(c)
属性添加到所有参数。
同样,在包装C函数时,必须使用intent(c)
属性来禁用Fortran特定的宏。<routine name>
F_FUNC(..,..)
cache
该参数被视为内存的垃圾。不执行Fortran或C连续性检查。使用intent(cache)
仅对数组参数有意义,也与
intent(hide)
或optional
属性有关。
copy
确保intent(in)
保留参数的原始内容。通常与intent(in,out)
属性结合使用。F2PY 使用默认值创建一个可选参数
。overwrite_<argument name>
0
overwrite
intent(in)
Fortran / C函数可能会更改参数的原始内容。F2PY 使用默认值
创建一个可选参数。overwrite_<argument name>
1
out=<new name>
在
包装函数的字符串中用替换返回名称。<new name>
__doc__
callback
构造一个适合从Fortran调用Python函数的外部函数。intent(callback)
必须在相应的external
语句之前指定。如果'argument'不在参数列表中,那么它将被添加到Python包装器中,但仅初始化外部函数。
使用intent(callback)
中的情况下一个Fortran / C ++代码假定一个用户实施与定原型并将其链接到可执行文件的功能。intent(callback)
如果函数出现在Fortran例程的参数列表中,请不要使用。
如果指定intent(hide)
或optional
属性,并且使用包装函数,而未在参数列表中指定回调参数,则在F2PY生成的扩展模块的命名空间中查看回调函数,用户可以将其设置为模块属性。
aux
在F2PY生成的包装函数中定义辅助C变量。保存参数值很有用,以便可以在其他变量的初始化表达式中访问它们。请注意,它
intent(aux)
暗含暗示intent(c)
。
适用以下规则:
如果未指定,
则假定为。intent(in | inout | out | hide)
intent(in)
intent(in,inout)
是intent(in)
。
intent(in,hide)
或者intent(inout,hide)
是
intent(hide)
。
intent(out)
是intent(out,hide)
除非intent(in)
或
intent(inout)
指定。
如果使用intent(copy)
或intent(overwrite)
,则会引入一个附加的可选参数,分别带有名称
和默认值0或1。overwrite_<argument name>
intent(inout,inplace)
是intent(inplace)
。
intent(in,inplace)
是intent(inplace)
。
intent(hide)
禁用optional
和required
。
check([<C-booleanexpr>])
通过评估执行参数的一致性检查
<C-booleanexpr>
; 如果<C-booleanexpr>
返回0,则引发异常。
如果check(..)
未使用,则F2PY会自动生成少量标准检查(例如,在使用数组参数的情况下,检查适当的形状和大小)。使用check()
由F2PY产生禁用检查。
depend([<names>])
这声明相应的参数取决于列表中变量的值<names>
。例如,<init_expr>
可以使用其他参数的值。使用depend(..)
属性给出的信息
,F2PY确保以正确的顺序初始化参数。如果depend(..)
未使用属性,则F2PY自动确定依赖关系。使用
depend()
由F2PY产生禁用的依赖关系。
在编辑最初由F2PY生成的依赖关系时,请注意不要破坏其他相关变量的依赖关系。要注意的另一件事是循环依赖性。F2PY在构造包装器时能够检测到循环依赖关系,并且会抱怨是否找到了循环依赖关系。
allocatable
对应的变量是定义为Fortran 90模块数据的Fortran 90可分配数组。
external
相应的参数是用户提供的功能。可以定义此所谓的回叫功能的签名
在__user__
模块块中
或通过在块中进行说明性(或真实的,如果签名文件是真实的Fortran代码)调用。<other statements>
例如,F2PY从
external cb_sub, cb_fun
integer n
real a(n),r
call cb_sub(a,n)
r = cb_fun(4)
以下回调签名:
subroutine cb_sub(a,n)
real dimension(n) :: a
integer optional,check(len(a)>=n),depend(a) :: n=len(a)
end subroutine cb_sub
function cb_fun(e_4_e) result (r)
integer :: e_4_e
real :: r
end function cb_fun
然后,用户提供的相应Python函数为:
def cb_sub(a,[n]):
...
return
def cb_fun(e_4_e):
...
return r
另请参阅intent(callback)
属性。
parameter
相应的变量是一个参数,并且必须具有固定值。F2PY将所有出现的参数替换为其对应的值。
所谓的F2PY指令允许在Fortran 77/90源代码中也使用F2PY签名文件结构。使用此功能,您可以跳过(几乎)完全中间的签名文件生成并将F2PY直接应用于Fortran源代码。
F2PY指令具有以下形式:
<comment char>f2py ...
固定和自由格式Fortran代码的允许注释字符分别为cC*!#
和!
。后面的所有内容
都会被编译器忽略,但由F2PY读取为常规的Fortran非注释行:<comment char>f2py
当F2PY找到带有F2PY伪指令的行时,该伪指令首先被5个空格代替,然后重新读取该行。
当然,对于固定格式的Fortran代码,必须位于文件的第一列。对于自由格式的Fortran代码,F2PY指令可以出现在文件中的任何位置。<comment char>
C表达式用于签名文件的以下部分:
<init_expr>
变量初始化;
<C-booleanexpr>
所述的check
属性;
<arrayspec> of the ``dimension
属性;
callstatement
语句,这里也可以使用C多行块。
AC表达式可能包含:
标准C构造;
来自math.h
和的功能Python.h
;
参数列表中的变量,可能是根据给定的依赖关系预先初始化的;
以下CPP宏:
rank(<name>)
返回数组的等级<name>
。
shape(<name>,<n>)
返回<n>
array 的第维度<name>
。
len(<name>)
返回数组的长度<name>
。
size(<name>)
返回数组的大小<name>
。
slen(<name>)
返回字符串的长度<name>
。
为了初始化数组,F2PY在所有索引和维度上生成一个循环,该循环执行以下伪语句:<array name>
<array name>(_i[0],_i[1],...) = <init_expr>;
其中_i[<i>]
指<i>
第-个索引值,从0
到。shape(<array name>,<i>)-1
例如,myrange(n)
根据以下签名生成的函数
subroutine myrange(a,n)
fortranname ! myrange is a dummy wrapper
integer intent(in) :: n
real*8 intent(c,out),dimension(n),depend(n) :: a = _i[0]
end subroutine myrange
等同于numpy.arange(n,dtype=float)
。
警告
扫描Fortran代码时,C2表达式中的F2PY也会小写(请参阅--[no]-lower
选项)。
多行块开头'''
(三重单引号),并与端部'''
在某些严格后续行。多行块只能在.pyf文件中使用。多行块的内容可以是任意的(除了不能包含'''
),并且不对其应用任何转换(例如,小写)。
当前,多行块可用于以下构造:
作为该callstatement
语句的C表达式;
作为该callprotoargument
语句的C类型规范;
作为该usercode
语句的C代码块;
作为该pymethoddef
语句的C数组的列表;
作为文档字符串。