Cython:创建扩展类型时是否必须手动实现 __getattr__ 方法?

Cython: does the __getattr__ method have to be manually implemented when creating an extension type?

假设我正在创建一个新的扩展类型:

cdef class foo:
    int x

    def __cinit__(self, x):
        self.x = x

我是否必须手动创建 __getattr__ special method?似乎是这样,因为 foo.__getattr__('x') 给我这样的错误:

ImportError: Building module simple_exttype failed: ["AttributeError: type object 'simple_exttypeexttype.foo' has no attribute '__getattr__'\n"]

请注意,我在 C-space 中尝试了以下内容,即我 运行 以下 *.pyx 文件:

cdef class foo:
    int x

    def __cinit__(self, x):
        self.x = x

myclass = foo(10)
print "myclass.__getattr__('x'): {}".format(myclass.__getattr__('x'))

如果一定要手动实现,如果不想用Python字典,应该怎么实现?

http://docs.cython.org/src/tutorial/cdef_classes.html 对此非常清楚(在页面的最后):

  • 属性默认只能从 Cython 访问(类型化访问)
  • 可以声明属性以将动态属性公开给 Python-space

所以这里有一个可行的方法(假设您想要将 x 公开为只读并修复代码中的拼写错误)——调用此 w.g cyt.pyx:

cdef class foo:
    cdef int _x

    def __cinit__(self, x):
        self._x = x

    property x:
        def __get__(self):
            return self._x

现在,一旦构建并安装:

>>> import cyt
>>> a = cyt.foo(23)
>>> a.x
23
>>> getattr(a, 'x')
23

我展示了内置 Python 函数 getattr 也可以工作——除了通过它或简单的 a.x 语法之外,没有任何理由获取属性。