使用 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 没有“每文件” skiponly 列表的概念,因此如果在 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>

包含语句插入在包装函数之前。此功能允许在 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/MacOSX 上的 : 和 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 交互。有关更多信息,请参阅其 常见问题解答

除了其他选项(见下文)和前面模式中描述的选项外,还可以使用以下选项。

注意

Changed in version 1.26.0: 现在可以使用两种独立的构建后端,distutilsmeson。强烈建议用户切换到 meson,因为它是在 Python 3.12 及更高版本上的默认值。

常见的构建标志

--backend <backend_type>

为编译过程指定构建后端。支持的后端是 mesondistutils。如果未指定,则默认为 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

有关更多信息,请参阅 构建 C 和 C++ 扩展 Python 文档以了解详细信息。

构建扩展模块时,对于非 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),请勿使用此选项。

Changed in version 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#

警告

Changed in version 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.cfortranobject.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 版本的主要站点包目录的写入权限。为了使结果包正常工作,您需要创建一个名为 __init__.py 的文件(与 add.pyf 相同的目录中)。请注意,扩展模块完全根据 add.pyfadd.f 文件定义。将 .pyf 文件转换为 .c 文件由 numpy.distutils 处理。