1ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot# This contains most of the executable examples from Guido's descr 2ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot# tutorial, once at 3ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot# 4ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot# http://www.python.org/2.2/descrintro.html 5ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot# 6ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot# A few examples left implicit in the writeup were fleshed out, a few were 7ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot# skipped due to lack of interest (e.g., faking super() by hand isn't 8ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot# of much interest anymore), and a few were fiddled to make the output 9ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot# deterministic. 10ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 11ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotfrom test.test_support import sortdict 12ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotimport pprint 13ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 14ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotclass defaultdict(dict): 15ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def __init__(self, default=None): 16ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot dict.__init__(self) 17ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.default = default 18ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 19ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def __getitem__(self, key): 20ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot try: 21ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot return dict.__getitem__(self, key) 22ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot except KeyError: 23ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot return self.default 24ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 25ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def get(self, key, *args): 26ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot if not args: 27ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot args = (self.default,) 28ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot return dict.get(self, key, *args) 29ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 30ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def merge(self, other): 31ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot for key in other: 32ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot if key not in self: 33ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self[key] = other[key] 34ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 35ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robottest_1 = """ 36ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 37ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotHere's the new type at work: 38ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 39ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> print defaultdict # show our type 40ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot <class 'test.test_descrtut.defaultdict'> 41ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> print type(defaultdict) # its metatype 42ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot <type 'type'> 43ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> a = defaultdict(default=0.0) # create an instance 44ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> print a # show the instance 45ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot {} 46ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> print type(a) # show its type 47ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot <class 'test.test_descrtut.defaultdict'> 48ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> print a.__class__ # show its class 49ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot <class 'test.test_descrtut.defaultdict'> 50ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> print type(a) is a.__class__ # its type is its class 51ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot True 52ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> a[1] = 3.25 # modify the instance 53ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> print a # show the new value 54ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot {1: 3.25} 55ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> print a[1] # show the new item 56ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 3.25 57ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> print a[0] # a non-existent item 58ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 0.0 59ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> a.merge({1:100, 2:200}) # use a dict method 60ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> print sortdict(a) # show the result 61ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot {1: 3.25, 2: 200} 62ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> 63ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 64ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotWe can also use the new type in contexts where classic only allows "real" 65ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotdictionaries, such as the locals/globals dictionaries for the exec 66ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotstatement or the built-in function eval(): 67ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 68ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> def sorted(seq): 69ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... seq.sort(key=str) 70ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... return seq 71ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> print sorted(a.keys()) 72ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot [1, 2] 73ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> exec "x = 3; print x" in a 74ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 3 75ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> print sorted(a.keys()) 76ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot [1, 2, '__builtins__', 'x'] 77ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> print a['x'] 78ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 3 79ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> 80ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 81ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotNow I'll show that defaultdict instances have dynamic instance variables, 82ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotjust like classic classes: 83ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 84ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> a.default = -1 85ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> print a["noway"] 86ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot -1 87ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> a.default = -1000 88ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> print a["noway"] 89ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot -1000 90ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> 'default' in dir(a) 91ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot True 92ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> a.x1 = 100 93ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> a.x2 = 200 94ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> print a.x1 95ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 100 96ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> d = dir(a) 97ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> 'default' in d and 'x1' in d and 'x2' in d 98ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot True 99ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> print sortdict(a.__dict__) 100ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot {'default': -1000, 'x1': 100, 'x2': 200} 101ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> 102ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot""" 103ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 104ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotclass defaultdict2(dict): 105ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot __slots__ = ['default'] 106ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 107ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def __init__(self, default=None): 108ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot dict.__init__(self) 109ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.default = default 110ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 111ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def __getitem__(self, key): 112ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot try: 113ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot return dict.__getitem__(self, key) 114ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot except KeyError: 115ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot return self.default 116ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 117ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def get(self, key, *args): 118ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot if not args: 119ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot args = (self.default,) 120ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot return dict.get(self, key, *args) 121ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 122ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def merge(self, other): 123ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot for key in other: 124ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot if key not in self: 125ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self[key] = other[key] 126ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 127ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robottest_2 = """ 128ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 129ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotThe __slots__ declaration takes a list of instance variables, and reserves 130ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotspace for exactly these in the instance. When __slots__ is used, other 131ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotinstance variables cannot be assigned to: 132ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 133ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> a = defaultdict2(default=0.0) 134ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> a[1] 135ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 0.0 136ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> a.default = -1 137ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> a[1] 138ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot -1 139ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> a.x1 = 1 140ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot Traceback (most recent call last): 141ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot File "<stdin>", line 1, in ? 142ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot AttributeError: 'defaultdict2' object has no attribute 'x1' 143ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> 144ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 145ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot""" 146ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 147ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robottest_3 = """ 148ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 149ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotIntrospecting instances of built-in types 150ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 151ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotFor instance of built-in types, x.__class__ is now the same as type(x): 152ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 153ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> type([]) 154ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot <type 'list'> 155ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> [].__class__ 156ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot <type 'list'> 157ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> list 158ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot <type 'list'> 159ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> isinstance([], list) 160ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot True 161ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> isinstance([], dict) 162ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot False 163ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> isinstance([], object) 164ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot True 165ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> 166ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 167ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotUnder the new proposal, the __methods__ attribute no longer exists: 168ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 169ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> [].__methods__ 170ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot Traceback (most recent call last): 171ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot File "<stdin>", line 1, in ? 172ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot AttributeError: 'list' object has no attribute '__methods__' 173ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> 174ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 175ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotInstead, you can get the same information from the list type: 176ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 177ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> pprint.pprint(dir(list)) # like list.__dict__.keys(), but sorted 178ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ['__add__', 179ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '__class__', 180ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '__contains__', 181ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '__delattr__', 182ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '__delitem__', 183ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '__delslice__', 184ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '__doc__', 185ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '__eq__', 186ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '__format__', 187ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '__ge__', 188ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '__getattribute__', 189ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '__getitem__', 190ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '__getslice__', 191ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '__gt__', 192ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '__hash__', 193ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '__iadd__', 194ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '__imul__', 195ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '__init__', 196ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '__iter__', 197ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '__le__', 198ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '__len__', 199ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '__lt__', 200ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '__mul__', 201ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '__ne__', 202ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '__new__', 203ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '__reduce__', 204ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '__reduce_ex__', 205ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '__repr__', 206ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '__reversed__', 207ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '__rmul__', 208ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '__setattr__', 209ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '__setitem__', 210ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '__setslice__', 211ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '__sizeof__', 212ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '__str__', 213ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '__subclasshook__', 214ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 'append', 215ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 'count', 216ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 'extend', 217ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 'index', 218ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 'insert', 219ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 'pop', 220ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 'remove', 221ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 'reverse', 222ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 'sort'] 223ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 224ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotThe new introspection API gives more information than the old one: in 225ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotaddition to the regular methods, it also shows the methods that are 226ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotnormally invoked through special notations, e.g. __iadd__ (+=), __len__ 227ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot(len), __ne__ (!=). You can invoke any method from this list directly: 228ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 229ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> a = ['tic', 'tac'] 230ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> list.__len__(a) # same as len(a) 231ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 2 232ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> a.__len__() # ditto 233ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 2 234ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> list.append(a, 'toe') # same as a.append('toe') 235ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> a 236ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ['tic', 'tac', 'toe'] 237ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> 238ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 239ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotThis is just like it is for user-defined classes. 240ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot""" 241ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 242ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robottest_4 = """ 243ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 244ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotStatic methods and class methods 245ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 246ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotThe new introspection API makes it possible to add static methods and class 247ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotmethods. Static methods are easy to describe: they behave pretty much like 248ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotstatic methods in C++ or Java. Here's an example: 249ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 250ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> class C: 251ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... 252ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... @staticmethod 253ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... def foo(x, y): 254ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... print "staticmethod", x, y 255ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 256ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> C.foo(1, 2) 257ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot staticmethod 1 2 258ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> c = C() 259ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> c.foo(1, 2) 260ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot staticmethod 1 2 261ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 262ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotClass methods use a similar pattern to declare methods that receive an 263ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotimplicit first argument that is the *class* for which they are invoked. 264ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 265ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> class C: 266ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... @classmethod 267ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... def foo(cls, y): 268ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... print "classmethod", cls, y 269ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 270ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> C.foo(1) 271ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot classmethod test.test_descrtut.C 1 272ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> c = C() 273ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> c.foo(1) 274ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot classmethod test.test_descrtut.C 1 275ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 276ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> class D(C): 277ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... pass 278ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 279ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> D.foo(1) 280ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot classmethod test.test_descrtut.D 1 281ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> d = D() 282ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> d.foo(1) 283ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot classmethod test.test_descrtut.D 1 284ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 285ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotThis prints "classmethod __main__.D 1" both times; in other words, the 286ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotclass passed as the first argument of foo() is the class involved in the 287ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotcall, not the class involved in the definition of foo(). 288ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 289ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotBut notice this: 290ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 291ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> class E(C): 292ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... @classmethod 293ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... def foo(cls, y): # override C.foo 294ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... print "E.foo() called" 295ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... C.foo(y) 296ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 297ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> E.foo(1) 298ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot E.foo() called 299ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot classmethod test.test_descrtut.C 1 300ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> e = E() 301ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> e.foo(1) 302ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot E.foo() called 303ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot classmethod test.test_descrtut.C 1 304ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 305ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotIn this example, the call to C.foo() from E.foo() will see class C as its 306ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotfirst argument, not class E. This is to be expected, since the call 307ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotspecifies the class C. But it stresses the difference between these class 308ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotmethods and methods defined in metaclasses (where an upcall to a metamethod 309ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotwould pass the target class as an explicit first argument). 310ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot""" 311ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 312ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robottest_5 = """ 313ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 314ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotAttributes defined by get/set methods 315ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 316ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 317ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> class property(object): 318ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... 319ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... def __init__(self, get, set=None): 320ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... self.__get = get 321ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... self.__set = set 322ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... 323ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... def __get__(self, inst, type=None): 324ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... return self.__get(inst) 325ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... 326ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... def __set__(self, inst, value): 327ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... if self.__set is None: 328ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... raise AttributeError, "this attribute is read-only" 329ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... return self.__set(inst, value) 330ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 331ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotNow let's define a class with an attribute x defined by a pair of methods, 332ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotgetx() and setx(): 333ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 334ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> class C(object): 335ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... 336ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... def __init__(self): 337ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... self.__x = 0 338ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... 339ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... def getx(self): 340ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... return self.__x 341ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... 342ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... def setx(self, x): 343ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... if x < 0: x = 0 344ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... self.__x = x 345ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... 346ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... x = property(getx, setx) 347ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 348ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotHere's a small demonstration: 349ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 350ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> a = C() 351ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> a.x = 10 352ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> print a.x 353ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 10 354ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> a.x = -10 355ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> print a.x 356ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 0 357ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> 358ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 359ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotHmm -- property is builtin now, so let's try it that way too. 360ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 361ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> del property # unmask the builtin 362ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> property 363ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot <type 'property'> 364ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 365ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> class C(object): 366ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... def __init__(self): 367ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... self.__x = 0 368ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... def getx(self): 369ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... return self.__x 370ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... def setx(self, x): 371ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... if x < 0: x = 0 372ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... self.__x = x 373ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... x = property(getx, setx) 374ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 375ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 376ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> a = C() 377ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> a.x = 10 378ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> print a.x 379ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 10 380ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> a.x = -10 381ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> print a.x 382ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 0 383ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot >>> 384ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot""" 385ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 386ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robottest_6 = """ 387ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 388ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotMethod resolution order 389ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 390ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotThis example is implicit in the writeup. 391ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 392ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot>>> class A: # classic class 393ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot... def save(self): 394ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot... print "called A.save()" 395ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot>>> class B(A): 396ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot... pass 397ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot>>> class C(A): 398ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot... def save(self): 399ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot... print "called C.save()" 400ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot>>> class D(B, C): 401ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot... pass 402ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 403ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot>>> D().save() 404ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotcalled A.save() 405ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 406ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot>>> class A(object): # new class 407ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot... def save(self): 408ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot... print "called A.save()" 409ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot>>> class B(A): 410ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot... pass 411ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot>>> class C(A): 412ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot... def save(self): 413ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot... print "called C.save()" 414ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot>>> class D(B, C): 415ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot... pass 416ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 417ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot>>> D().save() 418ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotcalled C.save() 419ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot""" 420ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 421ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotclass A(object): 422ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def m(self): 423ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot return "A" 424ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 425ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotclass B(A): 426ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def m(self): 427ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot return "B" + super(B, self).m() 428ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 429ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotclass C(A): 430ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def m(self): 431ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot return "C" + super(C, self).m() 432ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 433ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotclass D(C, B): 434ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def m(self): 435ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot return "D" + super(D, self).m() 436ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 437ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 438ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robottest_7 = """ 439ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 440ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotCooperative methods and "super" 441ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 442ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot>>> print D().m() # "DCBA" 443ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotDCBA 444ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot""" 445ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 446ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robottest_8 = """ 447ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 448ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotBackwards incompatibilities 449ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 450ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot>>> class A: 451ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot... def foo(self): 452ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot... print "called A.foo()" 453ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 454ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot>>> class B(A): 455ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot... pass 456ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 457ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot>>> class C(A): 458ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot... def foo(self): 459ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot... B.foo(self) 460ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 461ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot>>> C().foo() 462ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotTraceback (most recent call last): 463ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ... 464ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotTypeError: unbound method foo() must be called with B instance as first argument (got C instance instead) 465ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 466ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot>>> class C(A): 467ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot... def foo(self): 468ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot... A.foo(self) 469ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot>>> C().foo() 470ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotcalled A.foo() 471ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot""" 472ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 473ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot__test__ = {"tut1": test_1, 474ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot "tut2": test_2, 475ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot "tut3": test_3, 476ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot "tut4": test_4, 477ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot "tut5": test_5, 478ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot "tut6": test_6, 479ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot "tut7": test_7, 480ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot "tut8": test_8} 481ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 482ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot# Magic test name that regrtest.py invokes *after* importing this module. 483ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot# This worms around a bootstrap problem. 484ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot# Note that doctest and regrtest both look in sys.argv for a "-v" argument, 485ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot# so this works as expected in both ways of running regrtest. 486ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotdef test_main(verbose=None): 487ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot # Obscure: import this module as test.test_descrtut instead of as 488ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot # plain test_descrtut because the name of this module works its way 489ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot # into the doctest examples, and unless the full test.test_descrtut 490ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot # business is used the name can change depending on how the test is 491ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot # invoked. 492ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot from test import test_support, test_descrtut 493ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot test_support.run_doctest(test_descrtut, verbose) 494ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 495ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot# This part isn't needed for regrtest, but for running the test directly. 496ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotif __name__ == "__main__": 497ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot test_main(1) 498