summaryrefslogtreecommitdiff
path: root/pypers/notes.txt
blob: 0f9a720c80238ee6d9d1665ad77b62c0fdf28023 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

  class SuperAware(type,Customizable):
      """Instances of SuperAware inherit a private attribute __sup
      which provide a handy way to call cooperative methods."""
      # DOES NOT WORK WITH NEW, calls (super).__new__, not (super.__new__)
      sup=super # default, customizable
      def __init__(cls,*args):
          setattr(cls,'_%s__sup' % cls.__name__,cls.sup(cls))
          super(SuperAware,cls).__init__(*args) # usual cooperative call


Notice that this trick comes from Guido himself (in his essay on
"Type/class unification")

Let me show how ``SuperAware`` can be used in practice. 

A common requirement for a class is the ability to count the number of its
instances. This is a quite easy problem: it is enough to increments a counter 
each time an instance of that class is initialized. However, this idea can
be implemented in the wrong way. i.e. naively one could implement
counting capabilities in a class without such capabilities by modifying the
``__init__`` method explicitly in the original source code. 
A better alternative is to follow the bottom-up approach and to implement 
the counting 
feature in a separate mix-in class: then the feature can be added to the
original class via multiple inheritance, without touching the source.
Moreover, the counter class becomes a reusable components that can be
useful for other problems, too. In order to use the mix-in approach, the 
``__init__`` method of the counter class must me cooperative. The 
SuperAware metaclass provides some syntactic sugar for this job:

 ::

  #<oopp.py>

  #  class WithCounter(object):
  #      """Mixin class counting the total number of its instances and storing 
  #         it in the class attribute count."""

  #      __metaclass__=SuperAware
  #      count=1 # class attribute (or static attribute in C++/Java terminology)
  
  #      def __init__(self,*args,**kw): 
  #          self.__sup.__init__(*args,**kw) # anonymous cooperative call
  #          type(self).counter+=1 # increments the class attribute

  #  class WithCounter(object):
  #      """Mixin class counting the total number of its instances and storing 
  #         it in the class attribute count."""

  #      count=1 # class attribute (or static attribute in C++/Java terminology)

  #      def __init__(self,*args,**kw):  
  #          super(WithCounter,self).__init__(*args,**kw) 
  #          # anonymous cooperative call
  #          type(self).counter+=1 # increments the class attribute