2017-03-27 8 views
0

Tutorial.pyx.pxdファイルからの定義の実現でない限り.pyx.pxdファイルが同じ名前を持つべきではないと言います。Cython:カウンターチュートリアル行動

両方が が同じコードを記述しないよう.pyxファイルの名前は、Cライブラリからの宣言と cqueue.pxdのファイルとは異なるされている必要があります。 という名前の.pyxファイルの横にある.pxdファイルは、.pyxファイルのコードのエクスポート宣言を定義します。 cqueue.pxdファイルには通常のCライブラリの宣言が含まれているため、 は、Cythonが と関連付けているのと同じ名前の.pyxファイルであってはなりません。

それは同じ名前が.pxd.pyxコードとは無関係なcdef extern CPP宣言であっても、これらの二つのファイルに与えられている場合にのみ、正常に動作するときしかし、私は、状況に遭遇しました。

py_test.pyx:

# distutils: language = c++ 

from py_test cimport Test 

def f(): 
    Test[double](2.) + 3. 

zzz.pyx:

# distutils: language = c++ 

from py_test cimport Test 

def f(): 
    Test[double](2.) + 3. 

py_test.pxd:

cdef extern from "cpp_test.h": 
    cdef cppclass Test[T]: 
     Test() 
     Test(T value) 
     T value 
    cdef Test[T] operator+[T](Test[T]&, T) 

cpp_test.h:

template<typename T> 
class Test { 
public: 
    T value; 
    Test():value(0){} 
    Test(T value):value(value){} 
    ~Test(){} 
}; 

template<typename T> 
Test<T> operator+(const Test<T>& x, T y) { 
    return Test<T>(x.value + y); 
} 

setup.py:

from distutils.core import setup 
from Cython.Build import cythonize 

setup(
    name = "demo", # unused 
# ext_modules = cythonize('py_test.pyx'), # ok 
    ext_modules = cythonize('zzz.pyx'), # Invalid operand types for '+' (Test[double]; double) 
) 

答えて

2

チュートリアルでは、それがファイルを見つけた場合.pyxと.pxdファイルが同じ名前を.pyxファイルは自動的にfrom pxd_file_with_the_same_name cimport *と同等のものをやるということである必要はありませんと言っている理由同じ名前で

同じ名前の無関係なファイルを避ける理由は、あなたが期待していないものがある場合は何かが混乱するのを避けるためです。


この特定のケースではCythonは率直ビットバギーである非会員C++の演算子インポートする方法に関係しています。 this previous questionを参照してください。

メンバー以外の演算子は、現在のモジュールスコープにcimportが含まれている場合(つまり、関連付けられたクラスをインポートするだけでは動作しない場合)、Cythonでのみ利用できます。残念ながらcimportする方法は、それは私の知っているが、あなたは

from py_test cimport * 

で開始するzzz.pyxを変更した場合、その後*演算子をcimportする管理しないと、それが動作する必要があることを直接ありません。 py_test.pyxは暗黙のうちにこれを行いますので、これ以上の変更はありません。


(私はアイデアのこの種をいじりみましたし、すぐにそれが仕事を得ることができませんでしたが、多分あなたは私よりも多くの運を持っています。このやる気あなたprevious question about complexに関して)

+0

ありがとう、それは私が必要としていたものです!私は 'operator +'をcimportingする別の方法を知っています(私の答えは以下を参照してください)。 – axil

1

operator+をcimportingのもう一つの方法は、このようなものです:

zzz.pyx

# distutils: language = c++ 

from py_test cimport Test, add 

def f(): 
    add(Test[double](2.), 3.) 

pytest.pxd:

cdef extern from "cpp_test.h": 
    cdef cppclass Test[T]: 
     Test() 
     Test(T value) 
     T value 
    cdef Test[T] add "operator+"[T](Test[T]&, T) 

cimport *よりも好ましい場合もありますが、オペレータ呼び出しのセマンティクスが変更されるため理想的ではありません。