1Subject: Re: The metaclass saga using Python 2From: Vladimir Marangozov <Vladimir.Marangozov@imag.fr> 3To: tim_one@email.msn.com (Tim Peters) 4Cc: python-list@cwi.nl 5Date: Wed, 5 Aug 1998 15:59:06 +0200 (DFT) 6 7[Tim] 8> 9> building-on-examples-tends-to-prevent-abstract-thrashing-ly y'rs - tim 10> 11 12OK, I stand corrected. I understand that anybody's interpretation of 13the meta-class concept is likely to be difficult to digest by others. 14 15Here's another try, expressing the same thing, but using the Python 16programming model, examples and, perhaps, more popular terms. 17 181. Classes. 19 20 This is pure Python of today. Sorry about the tutorial, but it is 21 meant to illustrate the second part, which is the one we're 22 interested in and which will follow the same development scenario. 23 Besides, newbies are likely to understand that the discussion is 24 affordable even for them :-) 25 26 a) Class definition 27 28 A class is meant to define the common properties of a set of objects. 29 A class is a "package" of properties. The assembly of properties 30 in a class package is sometimes called a class structure (which isn't 31 always appropriate). 32 33 >>> class A: 34 attr1 = "Hello" # an attribute of A 35 def method1(self, *args): pass # method1 of A 36 def method2(self, *args): pass # method2 of A 37 >>> 38 39 So far, we defined the structure of the class A. The class A is 40 of type <class>. We can check this by asking Python: "what is A?" 41 42 >>> A # What is A? 43 <class __main__.A at 2023e360> 44 45 b) Class instantiation 46 47 Creating an object with the properties defined in the class A is 48 called instantiation of the class A. After an instantiation of A, we 49 obtain a new object, called an instance, which has the properties 50 packaged in the class A. 51 52 >>> a = A() # 'a' is the 1st instance of A 53 >>> a # What is 'a'? 54 <__main__.A instance at 2022b9d0> 55 56 >>> b = A() # 'b' is another instance of A 57 >>> b # What is 'b'? 58 <__main__.A instance at 2022b9c0> 59 60 The objects, 'a' and 'b', are of type <instance> and they both have 61 the same properties. Note, that 'a' and 'b' are different objects. 62 (their adresses differ). This is a bit hard to see, so let's ask Python: 63 64 >>> a == b # Is 'a' the same object as 'b'? 65 0 # No. 66 67 Instance objects have one more special property, indicating the class 68 they are an instance of. This property is named __class__. 69 70 >>> a.__class__ # What is the class of 'a'? 71 <class __main__.A at 2023e360> # 'a' is an instance of A 72 >>> b.__class__ # What is the class of 'b'? 73 <class __main__.A at 2023e360> # 'b' is an instance of A 74 >>> a.__class__ == b.__class__ # Is it really the same class A? 75 1 # Yes. 76 77 c) Class inheritance (class composition and specialization) 78 79 Classes can be defined in terms of other existing classes (and only 80 classes! -- don't bug me on this now). Thus, we can compose property 81 packages and create new ones. We reuse the property set defined 82 in a class by defining a new class, which "inherits" from the former. 83 In other words, a class B which inherits from the class A, inherits 84 the properties defined in A, or, B inherits the structure of A. 85 86 In the same time, at the definition of the new class B, we can enrich 87 the inherited set of properties by adding new ones and/or modify some 88 of the inherited properties. 89 90 >>> class B(A): # B inherits A's properties 91 attr2 = "World" # additional attr2 92 def method2(self, arg1): pass # method2 is redefined 93 def method3(self, *args): pass # additional method3 94 95 >>> B # What is B? 96 <class __main__.B at 2023e500> 97 >>> B == A # Is B the same class as A? 98 0 # No. 99 100 Classes define one special property, indicating whether a class 101 inherits the properties of another class. This property is called 102 __bases__ and it contains a list (a tuple) of the classes the new 103 class inherits from. The classes from which a class is inheriting the 104 properties are called superclasses (in Python, we call them also -- 105 base classes). 106 107 >>> A.__bases__ # Does A have any superclasses? 108 () # No. 109 >>> B.__bases__ # Does B have any superclasses? 110 (<class __main__.A at 2023e360>,) # Yes. It has one superclass. 111 >>> B.__bases__[0] == A # Is it really the class A? 112 1 # Yes, it is. 113 114-------- 115 116 Congratulations on getting this far! This was the hard part. 117 Now, let's continue with the easy one. 118 119-------- 120 1212. Meta-classes 122 123 You have to admit, that an anonymous group of Python wizards are 124 not satisfied with the property packaging facilities presented above. 125 They say, that the Real-World bugs them with problems that cannot be 126 modelled successfully with classes. Or, that the way classes are 127 implemented in Python and the way classes and instances behave at 128 runtime isn't always appropriate for reproducing the Real-World's 129 behavior in a way that satisfies them. 130 131 Hence, what they want is the following: 132 133 a) leave objects as they are (instances of classes) 134 b) leave classes as they are (property packages and object creators) 135 136 BUT, at the same time: 137 138 c) consider classes as being instances of mysterious objects. 139 d) label mysterious objects "meta-classes". 140 141 Easy, eh? 142 143 You may ask: "Why on earth do they want to do that?". 144 They answer: "Poor soul... Go and see how cruel the Real-World is!". 145 You - fuzzy: "OK, will do!" 146 147 And here we go for another round of what I said in section 1 -- Classes. 148 149 However, be warned! The features we're going to talk about aren't fully 150 implemented yet, because the Real-World don't let wizards to evaluate 151 precisely how cruel it is, so the features are still highly-experimental. 152 153 a) Meta-class definition 154 155 A meta-class is meant to define the common properties of a set of 156 classes. A meta-class is a "package" of properties. The assembly 157 of properties in a meta-class package is sometimes called a meta-class 158 structure (which isn't always appropriate). 159 160 In Python, a meta-class definition would have looked like this: 161 162 >>> metaclass M: 163 attr1 = "Hello" # an attribute of M 164 def method1(self, *args): pass # method1 of M 165 def method2(self, *args): pass # method2 of M 166 >>> 167 168 So far, we defined the structure of the meta-class M. The meta-class 169 M is of type <metaclass>. We cannot check this by asking Python, but 170 if we could, it would have answered: 171 172 >>> M # What is M? 173 <metaclass __main__.M at 2023e4e0> 174 175 b) Meta-class instantiation 176 177 Creating an object with the properties defined in the meta-class M is 178 called instantiation of the meta-class M. After an instantiation of M, 179 we obtain a new object, called an class, but now it is called also 180 a meta-instance, which has the properties packaged in the meta-class M. 181 182 In Python, instantiating a meta-class would have looked like this: 183 184 >>> A = M() # 'A' is the 1st instance of M 185 >>> A # What is 'A'? 186 <class __main__.A at 2022b9d0> 187 188 >>> B = M() # 'B' is another instance of M 189 >>> B # What is 'B'? 190 <class __main__.B at 2022b9c0> 191 192 The metaclass-instances, A and B, are of type <class> and they both 193 have the same properties. Note, that A and B are different objects. 194 (their adresses differ). This is a bit hard to see, but if it was 195 possible to ask Python, it would have answered: 196 197 >>> A == B # Is A the same class as B? 198 0 # No. 199 200 Class objects have one more special property, indicating the meta-class 201 they are an instance of. This property is named __metaclass__. 202 203 >>> A.__metaclass__ # What is the meta-class of A? 204 <metaclass __main__.M at 2023e4e0> # A is an instance of M 205 >>> A.__metaclass__ # What is the meta-class of B? 206 <metaclass __main__.M at 2023e4e0> # B is an instance of M 207 >>> A.__metaclass__ == B.__metaclass__ # Is it the same meta-class M? 208 1 # Yes. 209 210 c) Meta-class inheritance (meta-class composition and specialization) 211 212 Meta-classes can be defined in terms of other existing meta-classes 213 (and only meta-classes!). Thus, we can compose property packages and 214 create new ones. We reuse the property set defined in a meta-class by 215 defining a new meta-class, which "inherits" from the former. 216 In other words, a meta-class N which inherits from the meta-class M, 217 inherits the properties defined in M, or, N inherits the structure of M. 218 219 In the same time, at the definition of the new meta-class N, we can 220 enrich the inherited set of properties by adding new ones and/or modify 221 some of the inherited properties. 222 223 >>> metaclass N(M): # N inherits M's properties 224 attr2 = "World" # additional attr2 225 def method2(self, arg1): pass # method2 is redefined 226 def method3(self, *args): pass # additional method3 227 228 >>> N # What is N? 229 <metaclass __main__.N at 2023e500> 230 >>> N == M # Is N the same meta-class as M? 231 0 # No. 232 233 Meta-classes define one special property, indicating whether a 234 meta-class inherits the properties of another meta-class. This property 235 is called __metabases__ and it contains a list (a tuple) of the 236 meta-classes the new meta-class inherits from. The meta-classes from 237 which a meta-class is inheriting the properties are called 238 super-meta-classes (in Python, we call them also -- super meta-bases). 239 240 >>> M.__metabases__ # Does M have any supermetaclasses? 241 () # No. 242 >>> N.__metabases__ # Does N have any supermetaclasses? 243 (<metaclass __main__.M at 2023e360>,) # Yes. It has a supermetaclass. 244 >>> N.__metabases__[0] == M # Is it really the meta-class M? 245 1 # Yes, it is. 246 247-------- 248 249 Triple congratulations on getting this far! 250 Now you know everything about meta-classes and the Real-World! 251 252<unless-wizards-want-meta-classes-be-instances-of-mysterious-objects!> 253 254-- 255 Vladimir MARANGOZOV | Vladimir.Marangozov@inrialpes.fr 256http://sirac.inrialpes.fr/~marangoz | tel:(+33-4)76615277 fax:76615252 257