本页描述了Cython扩展类型当前支持的特殊方法。所有特殊方法的完整列表显示在底部的表中。其中一些方法的行为不同于Python的对应方法,或没有直接的Python对应方法,需要特别提及。
声明
扩展类型的特殊方法必须用def,而不是cdef声明。这不会影响他们的性能 - Python使用不同的调用约定来调用这些特殊方法。
初始化方法:__cinit __() 和__init __()
有两种方法与初始化对象有关。
__cinit __()方法是您应该执行对象的基本C级初始化,包括对象将拥有的任何C数据结构的分配。你需要小心你在__cinit __()方法中做什么,因为对象可能还不是完全有效的Python 对象。因此,你应该小心调用任何Python 可能触摸对象的操作;特别是其方法。
在调用__cinit __()方法时,已经为对象分配了内存,并且任何C属性已初始化为0或null。(任何Python属性也被初始化为None,但是你可能不应该依赖它。)你的__cinit __()方法保证被调用一次。
如果您的扩展类型具有基本类型,那么在调用__cinit __()方法之前,将自动调用基本类型的__cinit __()方法;您不能显式调用继承的__cinit __()方法。如果需要将修改的参数列表传递给基本类型,您将必须在__init __()方法中执行初始化的相关部分(其中调用继承方法的正常规则适用)。
在__cinit __()方法中不能安全地完成的任何初始化都应该在__init __()方法中完成。当调用__init __()时,对象是一个完全有效的Python对象,所有操作都是安全的。在某些情况下,__init __()可能被多次调用或根本不被调用,所以你的其他方法应该设计为在这种情况下稳健。
传递给构造函数的任何参数都将传递给__cinit __()方法和__init __()方法。如果你预计在Python中继承你的扩展类型,您可能会发现有用的是给__cinit __()方法*和**参数,以便它可以接受和忽略额外的参数。否则,任何具有带有不同签名的__init __()的Python子类都必须覆盖__new __()[1]以及__init __(),Python类的作者不会希望这样做。或者,为了方便起见,如果你声明你的__cinit__`()方法没有参数(除了self),它将简单地忽略传递给构造函数的任何额外的参数,而不会抱怨签名不匹配。
析构方法:__dealloc __()
__cinit __()方法的对应方法是__dealloc __()方法,它应该执行__cinit __()方法的逆。您在__cinit __()方法中显式分配的任何C数据(例如通过malloc)应在__dealloc __()方法中释放。你需要小心你在__dealloc __()方法中做什么。在调用__dealloc __()方法时,对象可能已经被部分销毁,并且对于Python而言可能不处于有效状态,所以你应该避免调用任何可能触摸对象的Python操作。特别是,不要调用对象的任何其他方法或做任何可能导致对象复活的事情。如果你坚持只是释放C数据是最好的。
你不需要担心释放对象的Python属性,因为在__dealloc __()方法返回后,它将由Cython完成。
当子类化扩展类型时,请注意,超类的__dealloc __()方法将始终被调用,即使它被覆盖。这与典型的Python行为不同,超类方法将不会被执行,除非它们被子类显式地调用。
注意:
- 扩展类型没有__del __()方法。
逻辑运算方法
算术运算符方法(如__add __())的行为与Python对应方法不同。这些方法没有单独的“反转”版本(__radd __()等)。相反,如果第一个操作数不能执行操作,则调用第二个操作数的相同方法,操作数的顺序相同。
运算比较操作
对于单个丰富的比较操作(__eq __(),__le __()等等)没有单独的方法。而是有一个方法__richcmp __(),它接受一个整数,指示要执行哪种操作,如下所示:
< | 0 |
== | 2 |
> | 4 |
<= | 1 |
!= | 3 |
>= | 5 |
特殊方法一览
此表列出了所有特殊方法及其参数和返回类型。在下表中,self的参数名称用于指示该参数具有该方法所属的类型。表中没有指定类型的其他参数是通用Python对象。
您不必将方法声明为采用这些参数类型。如果您声明不同类型,则会根据需要执行转换。
注意:
- (1)缓冲区接口旨在由C代码使用,不能直接从Python访问。它在Python / C API参考手册中的Python 2.x 6.6节和10.6节中描述。它在Python 2.6中被新的PEP 3118缓冲区协议取代,并且在Python 3中不再可用。有关新API的操作指南,请参阅实现缓冲区协议。
- 描述符对象是新式Python类的支持机制的一部分。请参阅Python文档中对描述符的讨论。另见PEP 252,“使类型看起来更像类”和PEP 253,“子类型内置类型”。
文章的脚注信息由WordPress的wp-posturl插件自动生成