関数を宣言するときに、def
、cdef
、およびcpdef
の違いを知りたいのですが。 defと他の人との違いは多かれ少なかれ明らかです。また、宣言に戻り値の型が追加されることもあります(cdef void/double/int... name
)そして時々そうではない。
また、cythonで文字列変数を宣言する方法も知りたいのですが、知らなかったので、オブジェクトとして宣言しました。
def
はPythonで関数を宣言します。 CythonはCランタイムに基づいているため、cdef
とcpdef
を使用できます。
cdef
は、C言語のレイヤーで関数を宣言します。ご存知のように(またはそうではありませんか?)、C言語では各関数の戻り値のタイプを定義する必要があります。関数がvoid
で返されることがありますが、これはPythonのreturn
と同じです。
Pythonはオブジェクト指向言語です。したがって、C++言語のレイヤーでクラスメソッドを定義し、サブクラスでこのメソッドをオーバーライドすることもできます。
cdef class A:
cdef foo(self):
print "A"
cdef class B(A)
cdef foo(self, x=None)
print "B", x
cdef class C(B):
cpdef foo(self, x=True, int k=3)
print "C", x, k
要約すると、なぜdef
、cdef
およびcpdef
を使用する必要があるのですか? Cythonを使用する場合、Pythonコードはコンパイル前にCコードに変換されるため、これにより、結果のCコードリストを制御できます。
詳細については、公式ドキュメントを読むことをお勧めします: http://docs.cython.org/src/reference/language_basics.html
主な違いは、関数をどこから呼び出すことができるかです。def
関数はPythonおよびCythonから呼び出すことができますが、cdef
関数はCythonおよびC。
どちらのタイプの関数も、型付き引数と型なし引数を任意に組み合わせて宣言できます。どちらの場合も、内部はCythonによってCにコンパイルされます(コンパイルされたコードは非常によく似ているはずです)。
# A Cython class for illustrative purposes
cdef class C:
pass
def f(int arg1, C arg2, arg3):
# takes an integer, a "C" and an untyped generic python object
pass
cdef g(int arg1, C arg2, arg3):
pass
上記の例では、f
はPython(Cythonモジュールをインポートした後)に表示され、g
は表示されず、Pythonから呼び出すことはできません。 。g
は、次のC署名に変換されます。
PyObject* some_name(int, struct __pyx_obj_11name_of_module_C *, PyObject*)
(ここで、struct __pyx_obj_11name_of_module_C *
は、クラスC
が変換されるC構造体です)。これにより、たとえば関数ポインタとしてC関数に渡すことができます。対照的に、f
は(簡単に)Cから呼び出すことはできません。
cdef
関数の制限:
cdef
関数は、他の関数内で定義できません。これは、キャプチャされた変数をC関数ポインタに格納する方法がないためです。例えば。次のコードは違法です。
# WON'T WORK!
def g(a):
cdef (int b):
return a+b
cdef
関数は*args
および**kwargs
型の引数を取ることができません。これは、C署名に簡単に変換できないためです。
cdef
関数の利点
cdef
関数は、Python同等のもの(ポインターなど)がないものを含め、任意のタイプの引数を取ることができます。def
関数は、これらを持たない必要があります。 Pythonから呼び出すことができます。
cdef
関数は戻り値の型を指定することもできます(指定されていない場合は、Pythonオブジェクト、CではPyObject*
)を返します。def
関数は常にPythonオブジェクトを返すため、戻り値の型を指定することはできません。
cdef int h(int* a):
# specify a return type and take a non-Python compatible argument
return a[0]
cdef
関数は、単純なC関数呼び出しに変換されるため、def
関数よりもすばやく呼び出すことができます。
cpdef
関数
cpdef
関数により、Cythonはcdef
関数(Cythonからの迅速な関数呼び出しを可能にする)とdef
関数(Pythonからの呼び出しを可能にする)を生成します。内部的には、def
関数はcdef
関数を呼び出すだけです。許可される引数のタイプに関して、cpdef
関数にはcdef
関数とdef
関数の両方のすべての制限があります。
cdef
関数を使用する場合
関数が呼び出されると、cdef
関数とdef
関数内のコードが実行される速度に違いはありません。したがって、次の場合にのみcdef
関数を使用してください。
頻繁に呼び出す場合はcpdef
関数を使用しますが(したがって、高速化された関数呼び出しが重要です)、Pythonから呼び出す必要があります。