python typedef用法_3. 定义扩展类型:已分类主题

3.5.Abstract Protocol Support¶

Python supports a variety of abstract ‘protocols;’ the specific interfaces

provided to use these interfaces are documented in 抽象对象层.

A number of these abstract interfaces were defined early in the development of

the Python implementation. In particular, the number, mapping, and sequence

protocols have been part of Python since the beginning. Other protocols have

been added over time. For protocols which depend on several handler routines

from the type implementation, the older protocols have been defined as optional

blocks of handlers referenced by the type object. For newer protocols there are

additional slots in the main type object, with a flag bit being set to indicate

that the slots are present and should be checked by the interpreter. (The flag

bit does not indicate that the slot values are non-NULL. The flag may be set

to indicate the presence of a slot, but a slot may still be unfilled.)

PyNumberMethods *tp_as_number;

PySequenceMethods *tp_as_sequence;

PyMappingMethods *tp_as_mapping;

If you wish your object to be able to act like a number, a sequence, or a

mapping object, then you place the address of a structure that implements the C

type PyNumberMethods, PySequenceMethods, or

PyMappingMethods, respectively. It is up to you to fill in this

structure with appropriate values. You can find examples of the use of each of

these in the Objects directory of the Python source distribution.

hashfunc tp_hash;

This function, if you choose to provide it, should return a hash number for an

instance of your data type. Here is a simple example:

static Py_hash_t

newdatatype_hash(newdatatypeobject *obj)

{

Py_hash_t result;

result = obj->some_size + 32767 * obj->some_number;

if (result == -1)

result = -2;

return result;

}

Py_hash_t is a signed integer type with a platform-varying width.

Returning -1 from tp_hash indicates an error,

which is why you should be careful to avoid returning it when hash computation

is successful, as seen above.

ternaryfunc tp_call;

This function is called when an instance of your data type is “called”, for

example, if obj1 is an instance of your data type and the Python script

contains obj1('hello'), the tp_call handler is invoked.

This function takes three arguments:

self is the instance of the data type which is the subject of the call.

If the call is obj1('hello'), then self is obj1.

args is a tuple containing the arguments to the call. You can use

PyArg_ParseTuple() to extract the arguments.

kwds is a dictionary of keyword arguments that were passed. If this is

non-NULL and you support keyword arguments, use

PyArg_ParseTupleAndKeywords() to extract the arguments. If you

do not want to support keyword arguments and this is non-NULL, raise a

TypeError with a message saying that keyword arguments are not supported.

Here is a toy tp_call implementation:

static PyObject *

newdatatype_call(newdatatypeobject *self, PyObject *args, PyObject *kwds)

{

PyObject *result;

char *arg1;

char *arg2;

char *arg3;

if (!PyArg_ParseTuple(args, "sss:call", &arg1, &arg2, &arg3)) {

return NULL;

}

result = PyUnicode_FromFormat(

"Returning -- value: [%d] arg1: [%s] arg2: [%s] arg3: [%s]\n",

obj->obj_UnderlyingDatatypePtr->size,

arg1, arg2, arg3);

return result;

}

/* Iterators */

getiterfunc tp_iter;

iternextfunc tp_iternext;

These functions provide support for the iterator protocol. Both handlers

take exactly one parameter, the instance for which they are being called,

and return a new reference. In the case of an error, they should set an

exception and return NULL. tp_iter corresponds

to the Python __iter__() method, while tp_iternext

corresponds to the Python __next__() method.

Any iterable object must implement the tp_iter

handler, which must return an iterator object. Here the same guidelines

apply as for Python classes:

For collections (such as lists and tuples) which can support multiple

independent iterators, a new iterator should be created and returned by

each call to tp_iter.

Objects which can only be iterated over once (usually due to side effects of

iteration, such as file objects) can implement tp_iter

by returning a new reference to themselves – and should also therefore

implement the tp_iternext handler.

Any iterator object should implement both tp_iter

and tp_iternext. An iterator’s

tp_iter handler should return a new reference

to the iterator. Its tp_iternext handler should

return a new reference to the next object in the iteration, if there is one.

If the iteration has reached the end, tp_iternext

may return NULL without setting an exception, or it may set

StopIteration in addition to returning NULL; avoiding

the exception can yield slightly better performance. If an actual error

occurs, tp_iternext should always set an exception

and return NULL.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值