4

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)

この問題を回避する方法について何か考えがありますか?

4

1 に答える 1

2
  • クラスで (public なしで) 属性を cdefining するとき、実際に行っているのは、C 構造体でいくつかのフィールドを定義することです。したがって、コンパイル (Cython + C) の後、属性の名前は失われ、C 構造体の先頭からのオフセットによってのみ識別されます。結果として、それらは Python からアクセスできません。

  • を追加するcdef publicと、Cython は、Python からのアクセスを許可するだけでなく、関連付け識別子 <--> オフセットを C 構造体に保持するプロパティアクセス関数を追加します。これらのプロパティ関数にはわずかなオーバーヘッドがあります。これらの関数は Python -> C 型のチェック/変換を実行することにも注意してください。

あなたの質問に答えるには、どうにかして関連付け ident <--> オフセットを維持する必要があります。高速にしたい場合、唯一の方法は手動で行うことです:

self.RE = param_list['RE']   # self.RE is a C struct access
self.Pr = param_list['Pr']
...
于 2014-06-02T20:35:50.940 に答える