cython - 如果有同名的属性,Cython 不能引用 cdef 类中的声明类型?
问题描述
我有一些包含 C++ 库的复杂生成的 cython 代码。
对于我包装的其中一个 C++ 库,我遇到了一个非常难以理解的错误。以下是一个最小的可重现示例
bad.pxd
:
cdef class Foo:
pass
cdef class Bar:
pass
bad.pyx
:
cdef class Bar:
x = {}
Bar.x['Foo'] = Foo
@property
def Foo(self):
pass
@Foo.setter
def Foo(self, val):
pass
来自 cython 编译器的错误:
Error compiling Cython file:
------------------------------------------------------------
...
cdef class Bar:
x = {}
Bar.x['Foo'] = Foo
^
------------------------------------------------------------
bad.pyx:4:19: 'Foo' is not a constant, variable or function identifier
如果我注释掉Bar.x['Foo'] = Foo
或注释掉属性,这编译得很好。
如果您还将该名称用作属性,则似乎无法引用该类型名称。如果它是一种方法,而不是属性,那么这样做似乎是可以的。
这是否违反了 Cython 中的某些规则,或者这更可能是一个错误?
我意识到正确的答案是“不要那样做”,但不幸的是,我无法控制导致这个公认的奇怪类定义的名称。
解决方案
最好的解决方法是
Bar.x['Foo'] = globals()['Foo'].
即使在您提到工作的某些情况下,它们也不会像您期望的那样做:如果Foo
是一种方法,那么 dict 最终会是:
{'Foo': <method 'Foo' of 'modulename.Bar' objects>}
(即不是 Python 行为)。
这可能是一个错误,但我怀疑修复它是否容易或优先级高,因为它是在编译时解决查找和属性不可分配的组合。前者几乎可以肯定是已知的并且可能无法修复。可以在问题跟踪器上报告错误。
推荐阅读
- testng - TestNG - 可以在测试执行报告中忽略数据提供者测试方法吗?
- php - 当我将所有图像都设置为 col-6 时,为什么我的图像会位于彼此下方?
- angular - NgRx 存储与选择器调用两次
- java - 在 Java 中执行 while(rs.next) 时跳过结果集的第一行
- mysql - Mysql2::Error: 指定的键太长;对于只有 87 db 字段的表,最大密钥长度为 767 字节
- openshift - 重命名 okd 集群的主节点的最佳方法是什么?
- angular - 父级中相同形式的两个子组件 - Angular
- amazon-web-services - 创建数据数组时如何在我的 appsync 中修复此错误
- reactjs - Search Console 中的 Google Crawler 无法使用 Github Page 在 React 中找到路由
- ios - Swift Firestore 更新字段值