• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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