使用 F2PY#
本页包含 f2py
命令的所有命令行选项的参考,以及 numpy.f2py
模块内部函数的参考。
将 f2py
用作命令行工具#
当用作命令行工具时,f2py
有三种主要模式,通过使用 -c
和 -h
开关来区分。
1. 签名文件生成#
要扫描 Fortran 源代码并生成签名文件,请使用
f2py -h <filename.pyf> <options> <fortran files> \
[[ only: <fortran functions> : ] \
[ skip: <fortran functions> : ]]... \
[<fortran files> ...]
注意
一个 Fortran 源文件可以包含许多例程,并且通常不需要允许所有例程都能从 Python 使用。在这种情况下,可以指定应封装哪些例程(在 only: .. :
部分中),或者指定 F2PY 应该忽略哪些例程(在 skip: .. :
部分中)。
F2PY 没有“按文件” skip
或 only
列表的概念,因此如果函数列在 only
中,则不会从任何其他文件中获取其他函数。
如果 <filename.pyf>
指定为 stdout
,则签名将写入标准输出而不是文件。
在此模式下,除了其他选项(见下文)外,还可以使用以下选项
--overwrite-signature
覆盖现有签名文件。
2. 扩展模块构建#
要构建扩展模块,请使用
f2py -m <modulename> <options> <fortran files> \
[[ only: <fortran functions> : ] \
[ skip: <fortran functions> : ]]... \
[<fortran files> ...]
构建的扩展模块将保存为 <modulename>module.c
到当前目录。
此处 <fortran files>
也可能包含签名文件。在此模式下,除了其他选项(见下文)外,还可以使用以下选项
--debug-capi
向扩展模块添加调试挂钩。使用此扩展模块时,有关包装器的各种诊断信息(例如变量值、执行步骤等)将写入标准输出。
-include'<includefile>'
向扩展模块源文件添加 CPP
#include
语句。<includefile>
应以下列形式之一给出"filename.ext" <filename.ext>
include 语句插入在包装函数之前。此功能允许在 F2PY 生成的包装器中使用任意 C 函数(在
<includefile>
中定义)。注意
此选项已弃用。请使用
usercode
语句直接在签名文件中指定 C 代码片段。--[no-]wrap-functions
为 Fortran 函数创建 Fortran 子程序包装器。
--wrap-functions
是默认选项,因为它确保了最大的可移植性和编译器独立性。--[no-]freethreading-compatible
创建一个模块,声明它是否需要 GIL。默认是
--no-freethreading-compatible
以实现向后兼容。在传递--freethreading-compatible
之前,请检查您正在封装的 Fortran 代码是否存在线程安全问题,因为f2py
不会分析 Fortran 代码的线程安全问题。--include-paths "<path1>:<path2>..."
从给定目录搜索包含文件。
注意
路径应由正确的操作系统分隔符
pathsep
分隔,即 Linux / MacOS 上的:
和 Windows 上的;
。在CMake
中,这对应于使用$<SEMICOLON>
。--help-link [<list of resources names>]
列出
numpy_distutils/system_info.py
找到的系统资源。例如,尝试f2py --help-link lapack_opt
。
3. 构建模块#
要构建扩展模块,请使用
f2py -c <options> <fortran files> \
[[ only: <fortran functions> : ] \
[ skip: <fortran functions> : ]]... \
[ <fortran/c source files> ] [ <.o, .a, .so files> ]
如果 <fortran files>
包含签名文件,则会构建扩展模块的源文件,编译所有 Fortran 和 C 源文件,最后将所有对象文件和库文件链接到扩展模块 <modulename>.so
,并保存到当前目录。
如果 <fortran files>
不包含签名文件,则在构建扩展模块之前,会通过扫描所有 Fortran 源代码以获取例程签名来构建扩展模块。
警告
从 Python 3.12 开始,distutils
已被移除。请改用环境变量或原生文件与 meson
交互。有关更多信息,请参阅其 FAQ。
除了其他选项(见下文)和前面模式中描述的选项之外,还可以使用以下选项。
注意
版本 1.26.0 中的变化:现在可以使用两种独立的构建后端:distutils
和 meson
。强烈建议用户切换到 meson
,因为它是 Python 3.12
及更高版本中的默认选项。
常见构建标志
--backend <backend_type>
指定编译过程的构建后端。支持的后端是
meson
和distutils
。如果未指定,则默认为distutils
。在 Python 3.12 或更高版本上,默认是meson
。--f77flags=<string>
指定 F77 编译器标志
--f90flags=<string>
指定 F90 编译器标志
--debug
使用调试信息编译
-l<libname>
链接时使用库
<libname>
。-D<macro>[=<defn=1>]
将宏
<macro>
定义为<defn>
。-U<macro>
定义宏
<macro>
-I<dir>
将目录
<dir>
添加到搜索包含文件的目录列表中。-L<dir>
将目录
<dir>
添加到搜索-l
的目录列表中。
与 meson
特定的标志是
--dep <dependency>
仅限 meson为模块指定 meson 依赖项。可以多次传递此参数以指定多个依赖项。依赖项存储在列表中以供进一步处理。示例:
--dep lapack --dep scalapack
这将把 “lapack” 和 “scalapack” 识别为依赖项,并从 argv 中移除它们,留下一个包含 [“lapack”, “scalapack”] 的依赖项列表。
较旧的 distutils
标志是
--help-fcompiler
不使用 meson列出可用的 Fortran 编译器。
--fcompiler=<Vendor>
不使用 meson按供应商指定 Fortran 编译器类型。
--f77exec=<path>
不使用 meson指定 F77 编译器的路径
--f90exec=<path>
不使用 meson指定 F90 编译器的路径
--opt=<string>
不使用 meson指定优化标志
--arch=<string>
不使用 meson指定架构特定的优化标志
--noopt
不使用 meson编译时禁用优化标志
--noarch
不使用 meson编译时禁用依赖于架构的优化标志
link-<resource>
不使用 meson将扩展模块与
numpy_distutils/system_info.py
定义的 <resource> 链接。例如,要与优化过的 LAPACK 库(MacOSX 上的 vecLib,其他地方的 ATLAS)链接,请使用--link-lapack_opt
。另请参见--help-link
开关。
注意
f2py -c
选项必须应用于现有 .pyf
文件(加上源/对象/库文件),或者必须指定 -m <modulename>
选项(加上源/对象/库文件)。使用以下选项之一
f2py -c -m fib1 fib1.f
或
f2py -m fib1 fib1.f -h fib1.pyf
f2py -c fib1.pyf fib1.f
有关更多信息,请参阅 Python 文档 构建 C 和 C++ 扩展 以了解详细信息。
构建扩展模块时,对于非 gcc Fortran 编译器,可能需要以下宏的组合
-DPREPEND_FORTRAN
-DNO_APPEND_FORTRAN
-DUPPERCASE_FORTRAN
要测试 F2PY 生成接口的性能,请使用 -DF2PY_REPORT_ATEXIT
。然后,在 Python 退出时会打印出各种计时报告。此功能可能并非在所有平台上都有效,目前仅支持 Linux。
要查看 F2PY 生成的接口是否对数组参数执行了复制,请使用 -DF2PY_REPORT_ON_ARRAY_COPY=<int>
。当数组参数的大小大于 <int>
时,会向 stderr
发送一条关于复制的消息。
其他选项#
-m <modulename>
扩展模块的名称。默认是
untitled
。
警告
如果使用了签名文件 (*.pyf
),请勿使用此选项。
版本 1.26.3 中的变化:如果提供了 pyf
文件,将忽略 -m
。
--[no-]lower
[不] 降低
<fortran files>
中的大小写。默认情况下,使用-h
开关时假定为--lower
,不使用-h
开关时假定为--no-lower
。-include<header>
在 C 包装器中写入额外的头文件,可以多次传递,每次生成 #include <header>。请注意,这应该用单引号传递且不带空格,例如
'-include<stdbool.h>'
--build-dir <dirname>
所有 F2PY 生成的文件都创建在
<dirname>
中。默认是tempfile.mkdtemp()
。--f2cmap <filename>
从给定文件加载 Fortran 到 C 的
KIND
规范。--quiet
静默运行。
--verbose
以额外详细模式运行。
--skip-empty-wrappers
除非输入要求,否则不生成包装器文件。这是一个向后兼容标志,用于恢复 1.22.4 版本之前的行为。
-v
打印 F2PY 版本并退出。
执行不带任何选项的 f2py
以获取可用选项的最新列表。
Python 模块 numpy.f2py
#
警告
版本 2.0.0 中的变化:以前有一个 f2py.compile
函数,该函数已被移除,用户可以通过 subprocess.run
手动封装 python -m numpy.f2py
,并根据需要设置环境变量以与 meson
交互。
当将 numpy.f2py
用作模块时,可以调用以下函数。
Fortran 到 Python 接口生成器。
版权所有 1999 – 2011 Pearu Peterson。版权所有 2011 – 至今 NumPy 开发者。根据 NumPy 许可证的条款,允许使用、修改和分发本软件。
不提供明示或暗示的保证。使用风险自负。
- numpy.f2py.get_include()[source]#
返回包含
fortranobject.c
和.h
文件的目录。注意
当直接从
.f
和/或.pyf
文件一次性使用numpy.distutils
构建扩展时,不需要此函数。使用 f2py 生成的代码构建的 Python 扩展模块需要使用
fortranobject.c
作为源文件,并包含fortranobject.h
头文件。此函数可用于获取包含这两个文件的目录。- 返回:
- include_pathstr
包含
fortranobject.c
和fortranobject.h
的目录的绝对路径。
另请参见
numpy.get_include
返回 numpy 包含目录的函数
备注
版本 1.21.1 中的新增功能。
除非您使用的构建系统对 f2py 有特定支持,否则使用
.pyf
签名文件构建 Python 扩展是一个两步过程。对于模块mymod
步骤 1:运行
python -m numpy.f2py mymod.pyf --quiet
。这将在mymod.pyf
旁边生成mymodmodule.c
和(如果需要)mymod-f2pywrappers.f
文件。步骤 2:构建您的 Python 扩展模块。这需要以下源文件
mymodmodule.c
mymod-f2pywrappers.f
(如果它是在步骤 1 中生成的)fortranobject.c
- numpy.f2py.run_main(comline_list)[source]#
等同于运行
f2py <args>
其中
<args>=string.join(<list>,' ')
,但在 Python 中。除非使用-h
,否则此函数返回一个字典,其中包含有关生成的模块及其对源文件的依赖关系的信息。您不能使用此函数构建扩展模块,也就是说,不允许使用
-c
。请改用compile
命令。示例
命令
f2py -m scalar scalar.f
可以从 Python 执行,如下所示。>>> import numpy.f2py >>> r = numpy.f2py.run_main(['-m','scalar','doc/source/f2py/scalar.f']) Reading fortran codes... Reading file 'doc/source/f2py/scalar.f' (format:fix,strict) Post-processing... Block: scalar Block: FOO Building modules... Building module "scalar"... Wrote C/API module "scalar" to file "./scalarmodule.c" >>> print(r) {'scalar': {'h': ['/home/users/pearu/src_cvs/f2py/src/fortranobject.h'], 'csrc': ['./scalarmodule.c', '/home/users/pearu/src_cvs/f2py/src/fortranobject.c']}}
自动扩展模块生成#
如果您想分发您的 f2py 扩展模块,那么您只需要包含 .pyf 文件和 Fortran 代码。NumPy 中的 distutils 扩展允许您完全根据此接口文件定义扩展模块。一个有效的 setup.py
文件(允许分发 add.f
模块,作为包 f2py_examples
的一部分,以便它可以作为 f2py_examples.add
加载)是
def configuration(parent_package='', top_path=None)
from numpy.distutils.misc_util import Configuration
config = Configuration('f2py_examples',parent_package, top_path)
config.add_extension('add', sources=['add.pyf','add.f'])
return config
if __name__ == '__main__':
from numpy.distutils.core import setup
setup(**configuration(top_path='').todict())
使用以下命令可以轻松安装新包
pip install .
假设您拥有向您正在使用的 Python 版本的主 site-packages 目录写入的适当权限。为了使生成的包正常工作,您需要创建一个名为 __init__.py
的文件(与 add.pyf
在同一目录中)。请注意,扩展模块完全是根据 add.pyf
和 add.f
文件定义的。.pyf 文件到 .c 文件的转换由 numpy.distutils
处理。