使用 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>..."从给定目录搜索 include 文件。
注意
路径应使用正确的操作系统分隔符
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>添加到搜索 include 文件的目录列表中。-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文件的目录。注意
当使用
numpy.distutils直接从.f和/或.pyf文件一次性构建扩展时,不需要此函数。使用 f2py 生成的代码构建的 Python 扩展模块需要使用
fortranobject.c作为源文件,并包含fortranobject.h头文件。此函数可用于获取包含这两个文件的目录。- 返回:
- include_pathstr
包含
fortranobject.c和fortranobject.h的目录的绝对路径。
另请参阅
numpy.get_include返回 numpy include 目录的函数
备注
新功能,版本 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.cmymod-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 使用版本的站点包主目录的适当权限。要使生成的包正常工作,您需要在(与 add.pyf 相同的目录中)创建一个名为 __init__.py 的文件。请注意,扩展模块完全根据 add.pyf 和 add.f 文件定义。.pyf 文件到 .c 文件的转换由 numpy.distutils 处理。
使用 Meson 构建(示例)#
将 f2py 与 Meson 一起使用#
Meson 是一个现代化的构建系统,推荐用于构建 Python 扩展模块,尤其是在 Python 3.12 和 NumPy 2.x 版本开始。Meson 提供了一种健壮且可维护的方式来使用 f2py 构建 Fortran 扩展。
要使用 f2py 和 Meson 构建 Fortran 扩展,您可以使用 Meson 的 custom_target 来调用 f2py 并生成扩展模块。以下最小示例演示了如何执行此操作
此示例显示了如何构建 add 扩展,该扩展来自 F2PY 示例 中描述的 add.f 和 add.pyf 文件(请注意,您并不总是需要 .pyf 文件:在许多情况下,f2py 可以自行确定注释)。
项目布局
- f2py_examples/
meson.build add.f add.pyf (可选) __init__.py (可为空)
示例 meson.build
project('f2py_examples', 'fortran')
py = import('python').find_installation()
# List your Fortran source files
sources = files('add.pyf', 'add.f')
# Build the extension by invoking f2py via a custom target
add_mod = custom_target(
'add_extension',
input: sources,
output: ['add' + py.extension_suffix()],
command: [
py.full_path(), '-m', 'numpy.f2py',
'-c', 'add.pyf', 'add.f',
'-m', 'add'
],
build_by_default: true
)
# Install into site-packages under the f2py_examples package
install_subdir('.', install_dir: join_paths(py.site_packages_dir(), 'f2py_examples'),
strip_directory: false,
exclude_files: ['meson.build'])
# Also install the built extension (place it beside __init__.py)
install_data(add_mod, install_dir: join_paths(py.site_packages_dir(), 'f2py_examples'))
有关更多详细信息和高级用法,请参阅用户文档中的 Meson 构建指南,或参考 SciPy 的 Meson 构建文件以获取真实示例:scipy/scipy