【问题标题】:tCommon imports cythont普通进口cython
【发布时间】:2020-02-28 17:22:00
【问题描述】:

我有一个文件结构

[CODE DIR]
- foo_1.pyx
- foo_1.pxd
- ...
- foo_n.pyx

大多数文件共享一些导入语句,即from cython cimport [somePackage]。

问题

我想拥有一个公用文件 foo_common.pyx,其中包含跨 foo_x.pyx 文件的共享导入,而无需复制其中的大部分。 foo_common.pyx 将包含例如

[foo_common.pyx]
cimport numpy as np
from cython.parallel cimport prange 
....

我尝试在 pyx 或 pxd 文件中堆叠一些常见定义,但 cython 似乎只看到类或其他定义,但没有。在 cython 中是否有可能在其中读取导入语句的通用“类似标题”的文件?

澄清

我有定义文件definitions.pxd:

[definitions.pxd]
cimport cython

我还有一些其他文件foo_1.pyx

[foo_1.pyx]
from definitions cimport *

@cython.cdivision(True)
cdef doing_something (int x):
     return x

将错误指出cdef function cannot take arbitrary decorators。 将cimport 更改为include 将完美运行。为什么这种行为不同?

事后看来,我找到了关于pxd 中可以共享定义的答案:

It cannot contain the implementations of any C or Python functions, or any Python class definitions, or any executable statements. 来自here。由于 cimport / import 语句忽略了任何其他定义,因此似乎 include 将是可行的方法;只有 C/C++ 相关定义。

【问题讨论】:

  • from cython cimport ...?您实际上并没有将您的模块命名为cython 是吗?因为这会立即与 Cython 编译器及其指令等发生冲突?

标签: python cython python-import


【解决方案1】:

Cython 有两种方法可以在多个 pyx-files 之间共享信息:

  • 使用cimport-mechanism 是类似于python 的更复杂的方式,类似于import。
  • 使用include 对应于将标头的内容转储到另一个文件中的低级C-ish 方式,即#include <xxx>。

您正在寻找的是第二个选项。例如将common.pxi 定义为:

# common.pxi
from libc.stdint cimport  int64_t   
ctypedef double float64
...

它可以在不同的pyx文件中使用,a.pyx:

# a.pyx:
include "common.pxi"  # definitions of float64_t, int64_t are now known

# float64_t, int64_t are used:
cdef doit_a(float64_t a, int64_t b):
    ....

和b.pyx:

# b.pyx:
include "common.pxi"  # definitions of float64_t, int64_t are now known

# float64_t, int64_t are used:
cdef doit_a(float64_t a, int64_t b):
    ....

虽然将 pxi-files 用于常见的 typedef 和 cimports,但也用于将 pyx 文件分成多个子部分,都是有效的用法 - 对于其他情况,pxd-files 是更好的选择,并且有时是唯一(理智)的选择(共享cdef class 的cdef-interface)。

pxd-files 的一个优点是可以更好地控制 cimport 的内容,类似于 import 可以通过 cimport 的所有内容

# definitions are in common.pxd
from common cimport *

但也可以选择仅 cimport 一些名称。

【讨论】:

  • 谢谢,这正是我想要的。是什么让(c)import 表现不同?也就是说,我有一个 common.pxd 不会从 cython 加载任何模块,即如果 common.pxd 包含一些导入 from libcpp.vector cimport vector 另一个 foo_x.pyx 不会看到这个导入。此外,为什么pxd 会是更好的选择?
  • @cvanelteren "cimport" 对应于 "import",它也不会将所有名称从导入的模块拖到全局命名空间中。但是,您可以使用 from ... cimport *,请参阅我的编辑。
  • 是的,我在发布之前尝试过,但它不像 include 那样提取定义 [参见更新原始帖子]
猜你喜欢
  • 2012-12-09
  • 2020-03-06
  • 1970-01-01
  • 2017-08-11
  • 2012-02-13
  • 2021-07-17
  • 1970-01-01
  • 1970-01-01
  • 2015-06-28
相关资源
最近更新 更多