【问题标题】:How to check whether a memmoryview in Null in cython如何在 cython 中检查 Null 中的内存视图是否存在
【发布时间】:2020-11-18 11:38:37
【问题描述】:

我想检查内存视图是否用 None 初始化。 我有这样的功能:

cdef void test(int[:] a):
    if a == NULL:
        print("invalid data")

cdef int[:] memview = None
test(memview)

编译时出现此错误:

Invalid types for '==' (int[:], void *)

将 None 分配给内存视图是否存在问题?如果不是这种情况,我该怎么做才能检测 NULL 值?

谢谢!

【问题讨论】:

  • None 是一个 Python 对象,NULL 是一个空的 C 指针。它们不是一回事
  • 这不是重点。主要问题是 memmoryview 和 null 没有可比性。我们如何检查 memmoryview 是否为空?
  • 我想你错过了我试图暗示的点:内存视图永远不是NULL。可能是None
  • 啊,我明白了。谢谢!我在 nogil 函数中使用它,这就是为什么我认为它不能是 python 对象。没有蟒蛇的东西吗?如果是这样,为什么我可以将它与 nogil 范围内的 memoryview 进行比较?
  • 我实际上有点惊讶它在nogil 块中工作。但是,与None 相比,不需要任何引用计数,最终会在 C 中作为简单的指针比较,所以我认为没有 GIL 应该是可能的。

标签: null cython memoryview typed-memory-views


【解决方案1】:

把我的 cmets 变成一个非常好的答案:

您正在将None 分配给您的内存视图:

cdef int[:] memview = None

因此,对照None,而不是对照NULL,检查它是有意义的:

if a is None:

最终它们是相似的概念但不同的东西:NULL 是一个不指向任何东西的指针,而None 是一个单例 Python 对象,它指示某些东西未设置。区别在于 C 级别和 Python 级别,这里的 memoryviews 行为“Python 级别”。


还有一个额外的细节可以让你在 nogil 块内执行 if a is None:Python 确保存在一个 None 对象(并且它在整个程序中保持相同的 None 对象)。因此可以将a is None 转换为C 代码

((PyObject *) __pyx_v_a.memview) == Py_None

即一个简单的指针比较,不需要 GIL,因为引用计数没有变化。

【讨论】:

  • 谢谢!这就是答案。 memmoryviews 是 python 对象吗?它们可以在 nogil 中使用,我们需要用 cdef 定义它们,所以我猜它们是 C 级别的。如果是这样的话,他们怎么可能是 None 呢?我以为这 None 会被翻译成 C Null 但显然我错了。
  • 它们不是 Python 对象。他们可以做的是包装一个导出 Python 缓冲区接口的 Python 对象。所以测试真的是“被包裹的对象是否设置为None?”真的是用NoneNULL 表示这是一个相当随意的决定。
猜你喜欢
  • 2023-03-23
  • 1970-01-01
  • 1970-01-01
  • 2014-06-08
  • 2021-09-23
  • 1970-01-01
  • 1970-01-01
  • 2010-11-21
  • 1970-01-01
相关资源
最近更新 更多