symbian-qemu-0.9.1-12/python-2.6.1/Demo/metaclasses/Meta.py
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 """Generic metaclass.
       
     2 
       
     3 XXX This is very much a work in progress.
       
     4 
       
     5 """
       
     6 
       
     7 import types
       
     8 
       
     9 class MetaMethodWrapper:
       
    10 
       
    11     def __init__(self, func, inst):
       
    12         self.func = func
       
    13         self.inst = inst
       
    14         self.__name__ = self.func.__name__
       
    15 
       
    16     def __call__(self, *args, **kw):
       
    17         return apply(self.func, (self.inst,) + args, kw)
       
    18 
       
    19 class MetaHelper:
       
    20 
       
    21     __methodwrapper__ = MetaMethodWrapper # For derived helpers to override
       
    22 
       
    23     def __helperinit__(self, formalclass):
       
    24         self.__formalclass__ = formalclass
       
    25 
       
    26     def __getattr__(self, name):
       
    27         # Invoked for any attr not in the instance's __dict__
       
    28         try:
       
    29             raw = self.__formalclass__.__getattr__(name)
       
    30         except AttributeError:
       
    31             try:
       
    32                 ga = self.__formalclass__.__getattr__('__usergetattr__')
       
    33             except (KeyError, AttributeError):
       
    34                 raise AttributeError, name
       
    35             return ga(self, name)
       
    36         if type(raw) != types.FunctionType:
       
    37             return raw
       
    38         return self.__methodwrapper__(raw, self)
       
    39 
       
    40 class MetaClass:
       
    41 
       
    42     """A generic metaclass.
       
    43 
       
    44     This can be subclassed to implement various kinds of meta-behavior.
       
    45 
       
    46     """
       
    47 
       
    48     __helper__ = MetaHelper             # For derived metaclasses to override
       
    49 
       
    50     __inited = 0
       
    51 
       
    52     def __init__(self, name, bases, dict):
       
    53         try:
       
    54             ga = dict['__getattr__']
       
    55         except KeyError:
       
    56             pass
       
    57         else:
       
    58             dict['__usergetattr__'] = ga
       
    59             del dict['__getattr__']
       
    60         self.__name__ = name
       
    61         self.__bases__ = bases
       
    62         self.__realdict__ = dict
       
    63         self.__inited = 1
       
    64 
       
    65     def __getattr__(self, name):
       
    66         try:
       
    67             return self.__realdict__[name]
       
    68         except KeyError:
       
    69             for base in self.__bases__:
       
    70                 try:
       
    71                     return base.__getattr__(name)
       
    72                 except AttributeError:
       
    73                     pass
       
    74             raise AttributeError, name
       
    75 
       
    76     def __setattr__(self, name, value):
       
    77         if not self.__inited:
       
    78             self.__dict__[name] = value
       
    79         else:
       
    80             self.__realdict__[name] = value
       
    81 
       
    82     def __call__(self, *args, **kw):
       
    83         inst = self.__helper__()
       
    84         inst.__helperinit__(self)
       
    85         try:
       
    86             init = inst.__getattr__('__init__')
       
    87         except AttributeError:
       
    88             init = lambda: None
       
    89         apply(init, args, kw)
       
    90         return inst
       
    91 
       
    92 
       
    93 Meta = MetaClass('Meta', (), {})
       
    94 
       
    95 
       
    96 def _test():
       
    97     class C(Meta):
       
    98         def __init__(self, *args):
       
    99             print "__init__, args =", args
       
   100         def m1(self, x):
       
   101             print "m1(x=%r)" % (x,)
       
   102     print C
       
   103     x = C()
       
   104     print x
       
   105     x.m1(12)
       
   106     class D(C):
       
   107         def __getattr__(self, name):
       
   108             if name[:2] == '__': raise AttributeError, name
       
   109             return "getattr:%s" % name
       
   110     x = D()
       
   111     print x.foo
       
   112     print x._foo
       
   113 ##     print x.__foo
       
   114 ##     print x.__foo__
       
   115 
       
   116 
       
   117 if __name__ == '__main__':
       
   118     _test()