1 # This contains most of the executable examples from Guido's descr
4 # http://www.python.org/2.2/descrintro.html
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
11 from test
.test_support
import sortdict
14 class defaultdict(dict):
15 def __init__(self
, default
=None):
17 self
.default
= default
19 def __getitem__(self
, key
):
21 return dict.__getitem
__(self
, key
)
25 def get(self
, key
, *args
):
27 args
= (self
.default
,)
28 return dict.get(self
, key
, *args
)
30 def merge(self
, other
):
33 self
[key
] = other
[key
]
37 Here's the new type at work:
39 >>> print defaultdict # show our type
40 <class 'test.test_descrtut.defaultdict'>
41 >>> print type(defaultdict) # its metatype
43 >>> a = defaultdict(default=0.0) # create an instance
44 >>> print a # show the instance
46 >>> print type(a) # show its type
47 <class 'test.test_descrtut.defaultdict'>
48 >>> print a.__class__ # show its class
49 <class 'test.test_descrtut.defaultdict'>
50 >>> print type(a) is a.__class__ # its type is its class
52 >>> a[1] = 3.25 # modify the instance
53 >>> print a # show the new value
55 >>> print a[1] # show the new item
57 >>> print a[0] # a non-existant item
59 >>> a.merge({1:100, 2:200}) # use a dict method
60 >>> print sortdict(a) # show the result
64 We can also use the new type in contexts where classic only allows "real"
65 dictionaries, such as the locals/globals dictionaries for the exec
66 statement or the built-in function eval():
71 >>> print sorted(a.keys())
73 >>> exec "x = 3; print x" in a
75 >>> print sorted(a.keys())
76 [1, 2, '__builtins__', 'x']
81 Now I'll show that defaultdict instances have dynamic instance variables,
82 just like classic classes:
90 >>> 'default' in dir(a)
97 >>> 'default' in d and 'x1' in d and 'x2' in d
99 >>> print sortdict(a.__dict__)
100 {'default': -1000, 'x1': 100, 'x2': 200}
104 class defaultdict2(dict):
105 __slots__
= ['default']
107 def __init__(self
, default
=None):
109 self
.default
= default
111 def __getitem__(self
, key
):
113 return dict.__getitem
__(self
, key
)
117 def get(self
, key
, *args
):
119 args
= (self
.default
,)
120 return dict.get(self
, key
, *args
)
122 def merge(self
, other
):
125 self
[key
] = other
[key
]
129 The __slots__ declaration takes a list of instance variables, and reserves
130 space for exactly these in the instance. When __slots__ is used, other
131 instance variables cannot be assigned to:
133 >>> a = defaultdict2(default=0.0)
140 Traceback (most recent call last):
141 File "<stdin>", line 1, in ?
142 AttributeError: 'defaultdict2' object has no attribute 'x1'
149 Introspecting instances of built-in types
151 For instance of built-in types, x.__class__ is now the same as type(x):
159 >>> isinstance([], list)
161 >>> isinstance([], dict)
163 >>> isinstance([], object)
167 Under the new proposal, the __methods__ attribute no longer exists:
170 Traceback (most recent call last):
171 File "<stdin>", line 1, in ?
172 AttributeError: 'list' object has no attribute '__methods__'
175 Instead, you can get the same information from the list type:
177 >>> pprint.pprint(dir(list)) # like list.__dict__.keys(), but sorted
221 The new introspection API gives more information than the old one: in
222 addition to the regular methods, it also shows the methods that are
223 normally invoked through special notations, e.g. __iadd__ (+=), __len__
224 (len), __ne__ (!=). You can invoke any method from this list directly:
226 >>> a = ['tic', 'tac']
227 >>> list.__len__(a) # same as len(a)
229 >>> a.__len__() # ditto
231 >>> list.append(a, 'toe') # same as a.append('toe')
233 ['tic', 'tac', 'toe']
236 This is just like it is for user-defined classes.
241 Static methods and class methods
243 The new introspection API makes it possible to add static methods and class
244 methods. Static methods are easy to describe: they behave pretty much like
245 static methods in C++ or Java. Here's an example:
251 ... print "staticmethod", x, y
259 Class methods use a similar pattern to declare methods that receive an
260 implicit first argument that is the *class* for which they are invoked.
265 ... print "classmethod", cls, y
268 classmethod test.test_descrtut.C 1
271 classmethod test.test_descrtut.C 1
277 classmethod test.test_descrtut.D 1
280 classmethod test.test_descrtut.D 1
282 This prints "classmethod __main__.D 1" both times; in other words, the
283 class passed as the first argument of foo() is the class involved in the
284 call, not the class involved in the definition of foo().
290 ... def foo(cls, y): # override C.foo
291 ... print "E.foo() called"
296 classmethod test.test_descrtut.C 1
300 classmethod test.test_descrtut.C 1
302 In this example, the call to C.foo() from E.foo() will see class C as its
303 first argument, not class E. This is to be expected, since the call
304 specifies the class C. But it stresses the difference between these class
305 methods and methods defined in metaclasses (where an upcall to a metamethod
306 would pass the target class as an explicit first argument).
311 Attributes defined by get/set methods
314 >>> class property(object):
316 ... def __init__(self, get, set=None):
320 ... def __get__(self, inst, type=None):
321 ... return self.__get(inst)
323 ... def __set__(self, inst, value):
324 ... if self.__set is None:
325 ... raise AttributeError, "this attribute is read-only"
326 ... return self.__set(inst, value)
328 Now let's define a class with an attribute x defined by a pair of methods,
329 getx() and and setx():
333 ... def __init__(self):
339 ... def setx(self, x):
343 ... x = property(getx, setx)
345 Here's a small demonstration:
356 Hmm -- property is builtin now, so let's try it that way too.
358 >>> del property # unmask the builtin
363 ... def __init__(self):
367 ... def setx(self, x):
370 ... x = property(getx, setx)
385 Method resolution order
387 This example is implicit in the writeup.
389 >>> class A: # classic class
391 ... print "called A.save()"
396 ... print "called C.save()"
403 >>> class A(object): # new class
405 ... print "called A.save()"
410 ... print "called C.save()"
424 return "B" + super(B
, self
).m()
428 return "C" + super(C
, self
).m()
432 return "D" + super(D
, self
).m()
437 Cooperative methods and "super"
439 >>> print D().m() # "DCBA"
445 Backwards incompatibilities
449 ... print "called A.foo()"
459 Traceback (most recent call last):
461 TypeError: unbound method foo() must be called with B instance as first argument (got C instance instead)
470 __test__
= {"tut1": test_1
,
479 # Magic test name that regrtest.py invokes *after* importing this module.
480 # This worms around a bootstrap problem.
481 # Note that doctest and regrtest both look in sys.argv for a "-v" argument,
482 # so this works as expected in both ways of running regrtest.
483 def test_main(verbose
=None):
484 # Obscure: import this module as test.test_descrtut instead of as
485 # plain test_descrtut because the name of this module works its way
486 # into the doctest examples, and unless the full test.test_descrtut
487 # business is used the name can change depending on how the test is
489 from test
import test_support
, test_descrtut
490 test_support
.run_doctest(test_descrtut
, verbose
)
492 # This part isn't needed for regrtest, but for running the test directly.
493 if __name__
== "__main__":