2017-02-10 4 views
4

私はこのURLで例を試しています。 http://cython.readthedocs.io/en/latest/src/userguide/buffer.htmlCythonバッファープロトコルの例エラー

私は以下を実行します。

import pyximport 
pyximport.install(build_dir = 'build') 
import ctest 

m = ctest.Matrix(10) 
m.add_row() 
print(m) 

私は

from cpython cimport Py_buffer 
from libcpp.vector cimport vector 

cdef class Matrix: 
    cdef Py_ssize_t ncols 
    cdef Py_ssize_t shape[2] 
    cdef Py_ssize_t strides[2] 
    cdef vector[float] v 

    def __cinit__(self, Py_ssize_t ncols): 
     self.ncols = ncols 

    def add_row(self): 
     """Adds a row, initially zero-filled.""" 
     self.v.extend(self.ncols) 
    ... 

このエラーとして定義されたクラスadd_rowで TypeError: 'int' object is not iterable

を言ってm.add_row()関数を呼び出すとき、これは私にエラーを与えるが、私に完全な意味がありますPythonのリストを拡張するのとまったく同じことをcythonのベクトル上で行うと仮定します。あなたはそれを数値に渡すのではなく、反復可能なオブジェクトをリストに追加します。

私はこれを行うことによって、それを修正することができます...

def add_row(self): 
    """Adds a row, initially zero-filled.""" 
    self.v.extend([0] * self.ncols) 

例のか、私が何かをしないのですかのタイプミスがあった場合、私はちょうど思っていました。また、ベクトルの拡張関数はどこから来ますか? cythonと一緒に配布されているvector.pxdファイルでは、拡張関数をインポートすることはありません。それはC++標準ライブラリにも存在しません。 cythonはベクター型で特別なことをしますか?

https://github.com/cython/cython/blob/master/Cython/Includes/libcpp/vector.pxd

答えて

2

vectorが自動的にPythonのリストに変換することができCPP。 self.v.extend([0] * self.ncols)という行のCコードを調べると、新しいpythonリストが作成されます:__pyx_t_2 = PyList_New(1 * ((__pyx_v_self->ncols<0) ? 0:__pyx_v_self->ncols))。したがって、extendは実際にはextendのpythonリストのメソッドです。

このような自動変換はまた、(jupyterノートに)コードを以下により確認することができる。

%%cython -+ 
from libcpp.vector cimport vector 

def test_cpp_vector_to_pylist(): 
    cdef vector[int] cv 
    for i in range(10): 
     cv.push_back(i) 
    return cv 

a = test_cpp_vector_to_pylist() 
print a  # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
print type(a) # <type 'list'> 

しかし、cvは、このような場合には、一時的なPythonのリストに変換され、元のCPP vertorは、未修飾続けます次のコードに示すように:

%%cython -+ 
from libcpp.vector cimport vector 

def test_cpp_vector_to_pylist_1(): 
    cdef vector[int] cv 
    for i in range(10): 
     cv.append(i) # Note: the append method of python list 
    return cv 

a = test_cpp_vector_to_pylist_1() 
print a  # [] 
print type(a) # <type 'list'> 

また、ACアレイも自動的にPythonのリストに変換することができる。

%%cython 

def test_c_array_to_pylist(): 
    cdef int i 
    cdef int[10] ca 
    for i in range(10): 
     ca[i] = i 
    return ca 

a = test_c_array_to_pylist() 
print a  # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
print type(a) # <type 'list'> 
+0

リストがベクトルに変換されないので、ベクトルが拡張されることはありません。 – DavidW

+0

そうです、別のコードスニペットを追加して表示してください。 – oz1