blob: 514e398787a6ba9f3de6c0fb643da6f6843e94e7 [file] [log] [blame]
Tim Peters95c99e52001-09-03 01:24:30 +00001# This contains most of the executable examples from Guido's descr
2# tutorial, once at
3#
4# http://www.python.org/2.2/descrintro.html
5#
6# A few examples left implicit in the writeup were fleshed out, a few were
7# skipped due to lack of interest (e.g., faking super() by hand isn't
8# of much interest anymore), and a few were fiddled to make the output
9# deterministic.
10
Barry Warsaw04f357c2002-07-23 19:04:11 +000011from test.test_support import sortdict
Tim Peters95c99e52001-09-03 01:24:30 +000012import pprint
13
Tim Petersa427a2b2001-10-29 22:25:45 +000014class defaultdict(dict):
Tim Peters95c99e52001-09-03 01:24:30 +000015 def __init__(self, default=None):
Tim Petersa427a2b2001-10-29 22:25:45 +000016 dict.__init__(self)
Tim Peters95c99e52001-09-03 01:24:30 +000017 self.default = default
18
19 def __getitem__(self, key):
20 try:
Tim Petersa427a2b2001-10-29 22:25:45 +000021 return dict.__getitem__(self, key)
Tim Peters95c99e52001-09-03 01:24:30 +000022 except KeyError:
23 return self.default
24
25 def get(self, key, *args):
26 if not args:
27 args = (self.default,)
Tim Petersa427a2b2001-10-29 22:25:45 +000028 return dict.get(self, key, *args)
Tim Peters95c99e52001-09-03 01:24:30 +000029
30 def merge(self, other):
31 for key in other:
32 if key not in self:
33 self[key] = other[key]
34
35test_1 = """
36
37Here's the new type at work:
38
39 >>> print defaultdict # show our type
Guido van Rossuma4cb7882001-09-25 03:56:29 +000040 <class 'test.test_descrtut.defaultdict'>
Tim Peters95c99e52001-09-03 01:24:30 +000041 >>> print type(defaultdict) # its metatype
42 <type 'type'>
43 >>> a = defaultdict(default=0.0) # create an instance
44 >>> print a # show the instance
45 {}
46 >>> print type(a) # show its type
Guido van Rossuma4cb7882001-09-25 03:56:29 +000047 <class 'test.test_descrtut.defaultdict'>
Tim Peters95c99e52001-09-03 01:24:30 +000048 >>> print a.__class__ # show its class
Guido van Rossuma4cb7882001-09-25 03:56:29 +000049 <class 'test.test_descrtut.defaultdict'>
Tim Peters95c99e52001-09-03 01:24:30 +000050 >>> print type(a) is a.__class__ # its type is its class
Guido van Rossum77f6a652002-04-03 22:41:51 +000051 True
Tim Peters95c99e52001-09-03 01:24:30 +000052 >>> a[1] = 3.25 # modify the instance
53 >>> print a # show the new value
54 {1: 3.25}
55 >>> print a[1] # show the new item
56 3.25
57 >>> print a[0] # a non-existant item
58 0.0
Tim Petersa427a2b2001-10-29 22:25:45 +000059 >>> a.merge({1:100, 2:200}) # use a dict method
Tim Peters95c99e52001-09-03 01:24:30 +000060 >>> print sortdict(a) # show the result
61 {1: 3.25, 2: 200}
62 >>>
63
64We can also use the new type in contexts where classic only allows "real"
65dictionaries, such as the locals/globals dictionaries for the exec
66statement or the built-in function eval():
67
68 >>> def sorted(seq):
69 ... seq.sort()
70 ... return seq
71 >>> print sorted(a.keys())
72 [1, 2]
73 >>> exec "x = 3; print x" in a
74 3
75 >>> print sorted(a.keys())
76 [1, 2, '__builtins__', 'x']
77 >>> print a['x']
78 3
79 >>>
80
Tim Peters95c99e52001-09-03 01:24:30 +000081Now I'll show that defaultdict instances have dynamic instance variables,
82just like classic classes:
83
84 >>> a.default = -1
85 >>> print a["noway"]
86 -1
87 >>> a.default = -1000
88 >>> print a["noway"]
89 -1000
Tim Peters5d2b77c2001-09-03 05:47:38 +000090 >>> 'default' in dir(a)
Guido van Rossum77f6a652002-04-03 22:41:51 +000091 True
Tim Peters95c99e52001-09-03 01:24:30 +000092 >>> a.x1 = 100
93 >>> a.x2 = 200
94 >>> print a.x1
95 100
Tim Peters5d2b77c2001-09-03 05:47:38 +000096 >>> d = dir(a)
97 >>> 'default' in d and 'x1' in d and 'x2' in d
Guido van Rossum77f6a652002-04-03 22:41:51 +000098 True
Tim Peterse2052ab2003-02-18 16:54:41 +000099 >>> print sortdict(a.__dict__)
100 {'default': -1000, 'x1': 100, 'x2': 200}
Tim Peters95c99e52001-09-03 01:24:30 +0000101 >>>
102"""
103
Tim Petersa427a2b2001-10-29 22:25:45 +0000104class defaultdict2(dict):
Tim Peters95c99e52001-09-03 01:24:30 +0000105 __slots__ = ['default']
106
107 def __init__(self, default=None):
Tim Petersa427a2b2001-10-29 22:25:45 +0000108 dict.__init__(self)
Tim Peters95c99e52001-09-03 01:24:30 +0000109 self.default = default
110
111 def __getitem__(self, key):
112 try:
Tim Petersa427a2b2001-10-29 22:25:45 +0000113 return dict.__getitem__(self, key)
Tim Peters95c99e52001-09-03 01:24:30 +0000114 except KeyError:
115 return self.default
116
117 def get(self, key, *args):
118 if not args:
119 args = (self.default,)
Tim Petersa427a2b2001-10-29 22:25:45 +0000120 return dict.get(self, key, *args)
Tim Peters95c99e52001-09-03 01:24:30 +0000121
122 def merge(self, other):
123 for key in other:
124 if key not in self:
125 self[key] = other[key]
126
127test_2 = """
128
129The __slots__ declaration takes a list of instance variables, and reserves
130space for exactly these in the instance. When __slots__ is used, other
131instance variables cannot be assigned to:
132
133 >>> a = defaultdict2(default=0.0)
134 >>> a[1]
135 0.0
136 >>> a.default = -1
137 >>> a[1]
138 -1
139 >>> a.x1 = 1
140 Traceback (most recent call last):
141 File "<stdin>", line 1, in ?
142 AttributeError: 'defaultdict2' object has no attribute 'x1'
143 >>>
144
145"""
146
147test_3 = """
148
149Introspecting instances of built-in types
150
151For instance of built-in types, x.__class__ is now the same as type(x):
152
153 >>> type([])
154 <type 'list'>
155 >>> [].__class__
156 <type 'list'>
157 >>> list
158 <type 'list'>
159 >>> isinstance([], list)
Guido van Rossum77f6a652002-04-03 22:41:51 +0000160 True
Tim Petersa427a2b2001-10-29 22:25:45 +0000161 >>> isinstance([], dict)
Guido van Rossum77f6a652002-04-03 22:41:51 +0000162 False
Tim Peters95c99e52001-09-03 01:24:30 +0000163 >>> isinstance([], object)
Guido van Rossum77f6a652002-04-03 22:41:51 +0000164 True
Tim Peters95c99e52001-09-03 01:24:30 +0000165 >>>
166
167Under the new proposal, the __methods__ attribute no longer exists:
168
169 >>> [].__methods__
170 Traceback (most recent call last):
171 File "<stdin>", line 1, in ?
172 AttributeError: 'list' object has no attribute '__methods__'
173 >>>
174
175Instead, you can get the same information from the list type:
176
177 >>> pprint.pprint(dir(list)) # like list.__dict__.keys(), but sorted
178 ['__add__',
179 '__class__',
180 '__contains__',
181 '__delattr__',
182 '__delitem__',
Guido van Rossum7b9144b2001-10-09 19:39:46 +0000183 '__delslice__',
Tim Peters80440552002-02-19 04:25:19 +0000184 '__doc__',
Tim Peters95c99e52001-09-03 01:24:30 +0000185 '__eq__',
Eric Smitha9f7d622008-02-17 19:46:49 +0000186 '__format__',
Tim Peters95c99e52001-09-03 01:24:30 +0000187 '__ge__',
Guido van Rossum867a8d22001-09-21 19:29:08 +0000188 '__getattribute__',
Tim Peters95c99e52001-09-03 01:24:30 +0000189 '__getitem__',
190 '__getslice__',
191 '__gt__',
192 '__hash__',
193 '__iadd__',
194 '__imul__',
195 '__init__',
Raymond Hettinger14bd6de2002-05-31 21:40:38 +0000196 '__iter__',
Tim Peters95c99e52001-09-03 01:24:30 +0000197 '__le__',
198 '__len__',
199 '__lt__',
200 '__mul__',
201 '__ne__',
202 '__new__',
Guido van Rossum3926a632001-09-25 16:25:58 +0000203 '__reduce__',
Guido van Rossumc53f0092003-02-18 22:05:12 +0000204 '__reduce_ex__',
Tim Peters95c99e52001-09-03 01:24:30 +0000205 '__repr__',
Raymond Hettingeraf28e4b2003-11-08 12:39:53 +0000206 '__reversed__',
Tim Peters95c99e52001-09-03 01:24:30 +0000207 '__rmul__',
208 '__setattr__',
209 '__setitem__',
210 '__setslice__',
211 '__str__',
Jeffrey Yasskin960b9b72008-02-28 04:45:36 +0000212 '__subclasshook__',
Tim Peters95c99e52001-09-03 01:24:30 +0000213 'append',
214 'count',
215 'extend',
216 'index',
217 'insert',
218 'pop',
219 'remove',
220 'reverse',
Raymond Hettinger64958a12003-12-17 20:43:33 +0000221 'sort']
Tim Peters95c99e52001-09-03 01:24:30 +0000222
223The new introspection API gives more information than the old one: in
224addition to the regular methods, it also shows the methods that are
225normally invoked through special notations, e.g. __iadd__ (+=), __len__
226(len), __ne__ (!=). You can invoke any method from this list directly:
227
228 >>> a = ['tic', 'tac']
229 >>> list.__len__(a) # same as len(a)
230 2
231 >>> a.__len__() # ditto
232 2
233 >>> list.append(a, 'toe') # same as a.append('toe')
234 >>> a
235 ['tic', 'tac', 'toe']
236 >>>
237
238This is just like it is for user-defined classes.
239"""
240
241test_4 = """
242
243Static methods and class methods
244
245The new introspection API makes it possible to add static methods and class
246methods. Static methods are easy to describe: they behave pretty much like
247static methods in C++ or Java. Here's an example:
248
249 >>> class C:
250 ...
Guido van Rossum5a8a0372005-01-16 00:25:31 +0000251 ... @staticmethod
Tim Peters95c99e52001-09-03 01:24:30 +0000252 ... def foo(x, y):
253 ... print "staticmethod", x, y
Tim Peters95c99e52001-09-03 01:24:30 +0000254
255 >>> C.foo(1, 2)
256 staticmethod 1 2
257 >>> c = C()
258 >>> c.foo(1, 2)
259 staticmethod 1 2
260
261Class methods use a similar pattern to declare methods that receive an
262implicit first argument that is the *class* for which they are invoked.
263
264 >>> class C:
Guido van Rossum5a8a0372005-01-16 00:25:31 +0000265 ... @classmethod
Tim Peters95c99e52001-09-03 01:24:30 +0000266 ... def foo(cls, y):
267 ... print "classmethod", cls, y
Tim Peters95c99e52001-09-03 01:24:30 +0000268
269 >>> C.foo(1)
Tim Peters90ba8d92001-09-09 01:21:31 +0000270 classmethod test.test_descrtut.C 1
Tim Peters95c99e52001-09-03 01:24:30 +0000271 >>> c = C()
272 >>> c.foo(1)
Tim Peters90ba8d92001-09-09 01:21:31 +0000273 classmethod test.test_descrtut.C 1
Tim Peters95c99e52001-09-03 01:24:30 +0000274
275 >>> class D(C):
276 ... pass
277
278 >>> D.foo(1)
Tim Peters90ba8d92001-09-09 01:21:31 +0000279 classmethod test.test_descrtut.D 1
Tim Peters95c99e52001-09-03 01:24:30 +0000280 >>> d = D()
281 >>> d.foo(1)
Tim Peters90ba8d92001-09-09 01:21:31 +0000282 classmethod test.test_descrtut.D 1
Tim Peters95c99e52001-09-03 01:24:30 +0000283
284This prints "classmethod __main__.D 1" both times; in other words, the
285class passed as the first argument of foo() is the class involved in the
286call, not the class involved in the definition of foo().
287
288But notice this:
289
290 >>> class E(C):
Guido van Rossum5a8a0372005-01-16 00:25:31 +0000291 ... @classmethod
Tim Peters95c99e52001-09-03 01:24:30 +0000292 ... def foo(cls, y): # override C.foo
293 ... print "E.foo() called"
294 ... C.foo(y)
Tim Peters95c99e52001-09-03 01:24:30 +0000295
296 >>> E.foo(1)
297 E.foo() called
Tim Peters90ba8d92001-09-09 01:21:31 +0000298 classmethod test.test_descrtut.C 1
Tim Peters95c99e52001-09-03 01:24:30 +0000299 >>> e = E()
300 >>> e.foo(1)
301 E.foo() called
Tim Peters90ba8d92001-09-09 01:21:31 +0000302 classmethod test.test_descrtut.C 1
Tim Peters95c99e52001-09-03 01:24:30 +0000303
304In this example, the call to C.foo() from E.foo() will see class C as its
305first argument, not class E. This is to be expected, since the call
306specifies the class C. But it stresses the difference between these class
307methods and methods defined in metaclasses (where an upcall to a metamethod
308would pass the target class as an explicit first argument).
309"""
310
311test_5 = """
312
313Attributes defined by get/set methods
314
315
Guido van Rossum8bce4ac2001-09-06 21:56:42 +0000316 >>> class property(object):
Tim Peters95c99e52001-09-03 01:24:30 +0000317 ...
318 ... def __init__(self, get, set=None):
319 ... self.__get = get
320 ... self.__set = set
321 ...
322 ... def __get__(self, inst, type=None):
323 ... return self.__get(inst)
324 ...
325 ... def __set__(self, inst, value):
326 ... if self.__set is None:
327 ... raise AttributeError, "this attribute is read-only"
328 ... return self.__set(inst, value)
329
330Now let's define a class with an attribute x defined by a pair of methods,
331getx() and and setx():
332
333 >>> class C(object):
334 ...
335 ... def __init__(self):
336 ... self.__x = 0
337 ...
338 ... def getx(self):
339 ... return self.__x
340 ...
341 ... def setx(self, x):
342 ... if x < 0: x = 0
343 ... self.__x = x
344 ...
Guido van Rossum8bce4ac2001-09-06 21:56:42 +0000345 ... x = property(getx, setx)
Tim Peters95c99e52001-09-03 01:24:30 +0000346
347Here's a small demonstration:
348
349 >>> a = C()
350 >>> a.x = 10
351 >>> print a.x
352 10
353 >>> a.x = -10
354 >>> print a.x
355 0
356 >>>
357
Guido van Rossum8bce4ac2001-09-06 21:56:42 +0000358Hmm -- property is builtin now, so let's try it that way too.
Tim Peters95c99e52001-09-03 01:24:30 +0000359
Guido van Rossum8bce4ac2001-09-06 21:56:42 +0000360 >>> del property # unmask the builtin
361 >>> property
362 <type 'property'>
Tim Peters95c99e52001-09-03 01:24:30 +0000363
364 >>> class C(object):
365 ... def __init__(self):
366 ... self.__x = 0
367 ... def getx(self):
368 ... return self.__x
369 ... def setx(self, x):
370 ... if x < 0: x = 0
371 ... self.__x = x
Guido van Rossum8bce4ac2001-09-06 21:56:42 +0000372 ... x = property(getx, setx)
Tim Peters95c99e52001-09-03 01:24:30 +0000373
374
375 >>> a = C()
376 >>> a.x = 10
377 >>> print a.x
378 10
379 >>> a.x = -10
380 >>> print a.x
381 0
382 >>>
383"""
384
385test_6 = """
386
387Method resolution order
388
389This example is implicit in the writeup.
390
391>>> class A: # classic class
392... def save(self):
393... print "called A.save()"
394>>> class B(A):
395... pass
396>>> class C(A):
397... def save(self):
398... print "called C.save()"
399>>> class D(B, C):
400... pass
401
402>>> D().save()
403called A.save()
404
405>>> class A(object): # new class
406... def save(self):
407... print "called A.save()"
408>>> class B(A):
409... pass
410>>> class C(A):
411... def save(self):
412... print "called C.save()"
413>>> class D(B, C):
414... pass
415
416>>> D().save()
417called C.save()
418"""
419
420class A(object):
421 def m(self):
422 return "A"
423
424class B(A):
425 def m(self):
426 return "B" + super(B, self).m()
427
428class C(A):
429 def m(self):
430 return "C" + super(C, self).m()
431
432class D(C, B):
433 def m(self):
434 return "D" + super(D, self).m()
435
436
437test_7 = """
438
439Cooperative methods and "super"
440
441>>> print D().m() # "DCBA"
442DCBA
443"""
444
445test_8 = """
446
447Backwards incompatibilities
448
449>>> class A:
450... def foo(self):
451... print "called A.foo()"
452
453>>> class B(A):
454... pass
455
456>>> class C(A):
457... def foo(self):
458... B.foo(self)
459
460>>> C().foo()
461Traceback (most recent call last):
462 ...
463TypeError: unbound method foo() must be called with B instance as first argument (got C instance instead)
464
465>>> class C(A):
466... def foo(self):
467... A.foo(self)
468>>> C().foo()
469called A.foo()
470"""
471
472__test__ = {"tut1": test_1,
473 "tut2": test_2,
474 "tut3": test_3,
475 "tut4": test_4,
476 "tut5": test_5,
477 "tut6": test_6,
478 "tut7": test_7,
479 "tut8": test_8}
480
481# Magic test name that regrtest.py invokes *after* importing this module.
482# This worms around a bootstrap problem.
483# Note that doctest and regrtest both look in sys.argv for a "-v" argument,
484# so this works as expected in both ways of running regrtest.
Tim Petersa0a62222001-09-09 06:12:01 +0000485def test_main(verbose=None):
486 # Obscure: import this module as test.test_descrtut instead of as
487 # plain test_descrtut because the name of this module works its way
488 # into the doctest examples, and unless the full test.test_descrtut
489 # business is used the name can change depending on how the test is
490 # invoked.
Barry Warsaw04f357c2002-07-23 19:04:11 +0000491 from test import test_support, test_descrtut
492 test_support.run_doctest(test_descrtut, verbose)
Tim Peters95c99e52001-09-03 01:24:30 +0000493
494# This part isn't needed for regrtest, but for running the test directly.
495if __name__ == "__main__":
Tim Petersa0a62222001-09-09 06:12:01 +0000496 test_main(1)