Cython无法使用setattr

时间:2014-06-02 02:35:50

标签: python cython setattr

我在cython中有一个cdef类,我想用setattr内置函数初始化它的字段。 但是,当我这样做时,我遇到了执行错误:

/path/.../cimul.cpython-34m.so in cimul.Simulation.__init__ (cimul.c:5100)()
AttributeError: 'Simulation' object has no attribute 'Re'

我的代码如下:

cdef class Simulation:
    cdef double Re, Pr, Ra, a, dt_security
    cdef int Nz, NFourier, freq_output, freq_critical_Ra, maxiter
    cdef bool verbose

    def __init__(self, *args, **kargs):
        param_list = {'Re': 1, 'Pr': 1, 'Ra': 1, 'a' : 1, 'Nz': 100,
                      'NFourier': 50, 'dt_security': 0.9,
                      'maxiter': 100, 'freq_output': 10,
                      'freq_critical_Ra':50, 'verbose': False}
        # save the default parameters
        for param, value in param_list.items():
            setattr(self, param, value)

你知道我怎么能绕过这个问题吗?

1 个答案:

答案 0 :(得分:2)

  • 当在类中cdefining(没有public)属性时,你真正在做的是在C结构中定义一些字段。因此,在编译(Cython + C)之后,属性的名称将丢失,它们仅通过从C结构的开头的某个偏移来标识。因此,无法从Python访问它们。

  • 如果添加cdef public,他们会在Cython中添加一些property访问函数,该函数不仅允许从Python访问,还保留关联标识符< - > C结构中的偏移量。通过这些属性功能会有轻微的开销。另请注意,这些函数执行Python - > C型检查/转换。

现在回答你的问题,你需要以某种方式保持关联ident< - >偏移。如果你想要快速的东西,唯一的方法是手工完成:

self.RE = param_list['RE']   # self.RE is a C struct access
self.Pr = param_list['Pr']
...