Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> |
2 | <html> | |
3 | <head> | |
4 | <link rel="STYLESHEET" href="ext.css" type='text/css' /> | |
5 | <link rel="SHORTCUT ICON" href="../icons/pyfav.png" type="image/png" /> | |
6 | <link rel='start' href='../index.html' title='Python Documentation Index' /> | |
7 | <link rel="first" href="ext.html" title='Extending and Embedding the Python Interpreter' /> | |
8 | <link rel='contents' href='contents.html' title="Contents" /> | |
9 | <link rel='last' href='about.html' title='About this document...' /> | |
10 | <link rel='help' href='about.html' title='About this document...' /> | |
11 | <link rel="next" href="node33.html" /> | |
12 | <link rel="prev" href="node31.html" /> | |
13 | <link rel="parent" href="dnt-type-methods.html" /> | |
14 | <link rel="next" href="node33.html" /> | |
15 | <meta name='aesop' content='information' /> | |
16 | <title>2.2.5 Abstract Protocol Support</title> | |
17 | </head> | |
18 | <body> | |
19 | <DIV CLASS="navigation"> | |
20 | <div id='top-navigation-panel' xml:id='top-navigation-panel'> | |
21 | <table align="center" width="100%" cellpadding="0" cellspacing="2"> | |
22 | <tr> | |
23 | <td class='online-navigation'><a rel="prev" title="2.2.4 Object Comparison" | |
24 | href="node31.html"><img src='../icons/previous.png' | |
25 | border='0' height='32' alt='Previous Page' width='32' /></A></td> | |
26 | <td class='online-navigation'><a rel="parent" title="2.2 Type Methods" | |
27 | href="dnt-type-methods.html"><img src='../icons/up.png' | |
28 | border='0' height='32' alt='Up One Level' width='32' /></A></td> | |
29 | <td class='online-navigation'><a rel="next" title="2.2.6 More Suggestions" | |
30 | href="node33.html"><img src='../icons/next.png' | |
31 | border='0' height='32' alt='Next Page' width='32' /></A></td> | |
32 | <td align="center" width="100%">Extending and Embedding the Python Interpreter</td> | |
33 | <td class='online-navigation'><a rel="contents" title="Table of Contents" | |
34 | href="contents.html"><img src='../icons/contents.png' | |
35 | border='0' height='32' alt='Contents' width='32' /></A></td> | |
36 | <td class='online-navigation'><img src='../icons/blank.png' | |
37 | border='0' height='32' alt='' width='32' /></td> | |
38 | <td class='online-navigation'><img src='../icons/blank.png' | |
39 | border='0' height='32' alt='' width='32' /></td> | |
40 | </tr></table> | |
41 | <div class='online-navigation'> | |
42 | <b class="navlabel">Previous:</b> | |
43 | <a class="sectref" rel="prev" href="node31.html">2.2.4 Object Comparison</A> | |
44 | <b class="navlabel">Up:</b> | |
45 | <a class="sectref" rel="parent" href="dnt-type-methods.html">2.2 Type Methods</A> | |
46 | <b class="navlabel">Next:</b> | |
47 | <a class="sectref" rel="next" href="node33.html">2.2.6 More Suggestions</A> | |
48 | </div> | |
49 | <hr /></div> | |
50 | </DIV> | |
51 | <!--End of Navigation Panel--> | |
52 | ||
53 | <H2><A NAME="SECTION004250000000000000000"> | |
54 | 2.2.5 Abstract Protocol Support</A> | |
55 | </H2> | |
56 | ||
57 | <P> | |
58 | Python supports a variety of <em>abstract</em> `protocols;' the specific | |
59 | interfaces provided to use these interfaces are documented in the | |
60 | <em class="citetitle"><a | |
61 | href="../api/api.html" | |
62 | title="Python/C API Reference Manual" | |
63 | >Python/C API Reference Manual</a></em> in the | |
64 | chapter ``<a class="ulink" href="../api/abstract.html" | |
65 | >Abstract Objects Layer</a>.'' | |
66 | ||
67 | <P> | |
68 | A number of these abstract interfaces were defined early in the | |
69 | development of the Python implementation. In particular, the number, | |
70 | mapping, and sequence protocols have been part of Python since the | |
71 | beginning. Other protocols have been added over time. For protocols | |
72 | which depend on several handler routines from the type implementation, | |
73 | the older protocols have been defined as optional blocks of handlers | |
74 | referenced by the type object. For newer protocols there are | |
75 | additional slots in the main type object, with a flag bit being set to | |
76 | indicate that the slots are present and should be checked by the | |
77 | interpreter. (The flag bit does not indicate that the slot values are | |
78 | non-<tt class="constant">NULL</tt>. The flag may be set to indicate the presence of a slot, | |
79 | but a slot may still be unfilled.) | |
80 | ||
81 | <P> | |
82 | <div class="verbatim"><pre> | |
83 | PyNumberMethods tp_as_number; | |
84 | PySequenceMethods tp_as_sequence; | |
85 | PyMappingMethods tp_as_mapping; | |
86 | </pre></div> | |
87 | ||
88 | <P> | |
89 | If you wish your object to be able to act like a number, a sequence, | |
90 | or a mapping object, then you place the address of a structure that | |
91 | implements the C type <tt class="ctype">PyNumberMethods</tt>, | |
92 | <tt class="ctype">PySequenceMethods</tt>, or <tt class="ctype">PyMappingMethods</tt>, respectively. | |
93 | It is up to you to fill in this structure with appropriate values. You | |
94 | can find examples of the use of each of these in the <span class="file">Objects</span> | |
95 | directory of the Python source distribution. | |
96 | ||
97 | <P> | |
98 | <div class="verbatim"><pre> | |
99 | hashfunc tp_hash; | |
100 | </pre></div> | |
101 | ||
102 | <P> | |
103 | This function, if you choose to provide it, should return a hash | |
104 | number for an instance of your data type. Here is a moderately | |
105 | pointless example: | |
106 | ||
107 | <P> | |
108 | <div class="verbatim"><pre> | |
109 | static long | |
110 | newdatatype_hash(newdatatypeobject *obj) | |
111 | { | |
112 | long result; | |
113 | result = obj->obj_UnderlyingDatatypePtr->size; | |
114 | result = result * 3; | |
115 | return result; | |
116 | } | |
117 | </pre></div> | |
118 | ||
119 | <P> | |
120 | <div class="verbatim"><pre> | |
121 | ternaryfunc tp_call; | |
122 | </pre></div> | |
123 | ||
124 | <P> | |
125 | This function is called when an instance of your data type is "called", | |
126 | for example, if <code>obj1</code> is an instance of your data type and the Python | |
127 | script contains <code>obj1('hello')</code>, the <tt class="member">tp_call</tt> handler is | |
128 | invoked. | |
129 | ||
130 | <P> | |
131 | This function takes three arguments: | |
132 | ||
133 | <P> | |
134 | ||
135 | <OL> | |
136 | <LI><var>arg1</var> is the instance of the data type which is the subject of | |
137 | the call. If the call is <code>obj1('hello')</code>, then <var>arg1</var> is | |
138 | <code>obj1</code>. | |
139 | ||
140 | <P> | |
141 | </LI> | |
142 | <LI><var>arg2</var> is a tuple containing the arguments to the call. You | |
143 | can use <tt class="cfunction">PyArg_ParseTuple()</tt> to extract the arguments. | |
144 | ||
145 | <P> | |
146 | </LI> | |
147 | <LI><var>arg3</var> is a dictionary of keyword arguments that were passed. | |
148 | If this is non-<tt class="constant">NULL</tt> and you support keyword arguments, use | |
149 | <tt class="cfunction">PyArg_ParseTupleAndKeywords()</tt> to extract the | |
150 | arguments. If you do not want to support keyword arguments and | |
151 | this is non-<tt class="constant">NULL</tt>, raise a <tt class="exception">TypeError</tt> with a message | |
152 | saying that keyword arguments are not supported. | |
153 | </LI> | |
154 | </OL> | |
155 | ||
156 | <P> | |
157 | Here is a desultory example of the implementation of the call function. | |
158 | ||
159 | <P> | |
160 | <div class="verbatim"><pre> | |
161 | /* Implement the call function. | |
162 | * obj1 is the instance receiving the call. | |
163 | * obj2 is a tuple containing the arguments to the call, in this | |
164 | * case 3 strings. | |
165 | */ | |
166 | static PyObject * | |
167 | newdatatype_call(newdatatypeobject *obj, PyObject *args, PyObject *other) | |
168 | { | |
169 | PyObject *result; | |
170 | char *arg1; | |
171 | char *arg2; | |
172 | char *arg3; | |
173 | ||
174 | if (!PyArg_ParseTuple(args, "sss:call", &arg1, &arg2, &arg3)) { | |
175 | return NULL; | |
176 | } | |
177 | result = PyString_FromFormat( | |
178 | "Returning -- value: [\%d] arg1: [\%s] arg2: [\%s] arg3: [\%s]\n", | |
179 | obj->obj_UnderlyingDatatypePtr->size, | |
180 | arg1, arg2, arg3); | |
181 | printf("\%s", PyString_AS_STRING(result)); | |
182 | return result; | |
183 | } | |
184 | </pre></div> | |
185 | ||
186 | <P> | |
187 | XXX some fields need to be added here... | |
188 | ||
189 | <P> | |
190 | <div class="verbatim"><pre> | |
191 | /* Added in release 2.2 */ | |
192 | /* Iterators */ | |
193 | getiterfunc tp_iter; | |
194 | iternextfunc tp_iternext; | |
195 | </pre></div> | |
196 | ||
197 | <P> | |
198 | These functions provide support for the iterator protocol. Any object | |
199 | which wishes to support iteration over its contents (which may be | |
200 | generated during iteration) must implement the <code>tp_iter</code> | |
201 | handler. Objects which are returned by a <code>tp_iter</code> handler must | |
202 | implement both the <code>tp_iter</code> and <code>tp_iternext</code> handlers. | |
203 | Both handlers take exactly one parameter, the instance for which they | |
204 | are being called, and return a new reference. In the case of an | |
205 | error, they should set an exception and return <tt class="constant">NULL</tt>. | |
206 | ||
207 | <P> | |
208 | For an object which represents an iterable collection, the | |
209 | <code>tp_iter</code> handler must return an iterator object. The iterator | |
210 | object is responsible for maintaining the state of the iteration. For | |
211 | collections which can support multiple iterators which do not | |
212 | interfere with each other (as lists and tuples do), a new iterator | |
213 | should be created and returned. Objects which can only be iterated | |
214 | over once (usually due to side effects of iteration) should implement | |
215 | this handler by returning a new reference to themselves, and should | |
216 | also implement the <code>tp_iternext</code> handler. File objects are an | |
217 | example of such an iterator. | |
218 | ||
219 | <P> | |
220 | Iterator objects should implement both handlers. The <code>tp_iter</code> | |
221 | handler should return a new reference to the iterator (this is the | |
222 | same as the <code>tp_iter</code> handler for objects which can only be | |
223 | iterated over destructively). The <code>tp_iternext</code> handler should | |
224 | return a new reference to the next object in the iteration if there is | |
225 | one. If the iteration has reached the end, it may return <tt class="constant">NULL</tt> | |
226 | without setting an exception or it may set <tt class="exception">StopIteration</tt>; | |
227 | avoiding the exception can yield slightly better performance. If an | |
228 | actual error occurs, it should set an exception and return <tt class="constant">NULL</tt>. | |
229 | ||
230 | <P> | |
231 | ||
232 | <DIV CLASS="navigation"> | |
233 | <div class='online-navigation'> | |
234 | <p></p><hr /> | |
235 | <table align="center" width="100%" cellpadding="0" cellspacing="2"> | |
236 | <tr> | |
237 | <td class='online-navigation'><a rel="prev" title="2.2.4 Object Comparison" | |
238 | href="node31.html"><img src='../icons/previous.png' | |
239 | border='0' height='32' alt='Previous Page' width='32' /></A></td> | |
240 | <td class='online-navigation'><a rel="parent" title="2.2 Type Methods" | |
241 | href="dnt-type-methods.html"><img src='../icons/up.png' | |
242 | border='0' height='32' alt='Up One Level' width='32' /></A></td> | |
243 | <td class='online-navigation'><a rel="next" title="2.2.6 More Suggestions" | |
244 | href="node33.html"><img src='../icons/next.png' | |
245 | border='0' height='32' alt='Next Page' width='32' /></A></td> | |
246 | <td align="center" width="100%">Extending and Embedding the Python Interpreter</td> | |
247 | <td class='online-navigation'><a rel="contents" title="Table of Contents" | |
248 | href="contents.html"><img src='../icons/contents.png' | |
249 | border='0' height='32' alt='Contents' width='32' /></A></td> | |
250 | <td class='online-navigation'><img src='../icons/blank.png' | |
251 | border='0' height='32' alt='' width='32' /></td> | |
252 | <td class='online-navigation'><img src='../icons/blank.png' | |
253 | border='0' height='32' alt='' width='32' /></td> | |
254 | </tr></table> | |
255 | <div class='online-navigation'> | |
256 | <b class="navlabel">Previous:</b> | |
257 | <a class="sectref" rel="prev" href="node31.html">2.2.4 Object Comparison</A> | |
258 | <b class="navlabel">Up:</b> | |
259 | <a class="sectref" rel="parent" href="dnt-type-methods.html">2.2 Type Methods</A> | |
260 | <b class="navlabel">Next:</b> | |
261 | <a class="sectref" rel="next" href="node33.html">2.2.6 More Suggestions</A> | |
262 | </div> | |
263 | </div> | |
264 | <hr /> | |
265 | <span class="release-info">Release 2.4.2, documentation updated on 28 September 2005.</span> | |
266 | </DIV> | |
267 | <!--End of Navigation Panel--> | |
268 | <ADDRESS> | |
269 | See <i><a href="about.html">About this document...</a></i> for information on suggesting changes. | |
270 | </ADDRESS> | |
271 | </BODY> | |
272 | </HTML> |