mirror of
https://github.com/python/cpython.git
synced 2025-11-01 18:51:43 +00:00
Arbitrary point checkpoint commit. Take no notice.
This commit is contained in:
parent
bff110f3f1
commit
27e4aa3168
4 changed files with 248 additions and 6 deletions
106
Demo/metaclasses/Meta.py
Normal file
106
Demo/metaclasses/Meta.py
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
"""Generic metaclass.
|
||||
|
||||
XXX This is very much a work in progress.
|
||||
|
||||
"""
|
||||
|
||||
import types
|
||||
|
||||
class MetaMethodWrapper:
|
||||
|
||||
def __init__(self, func, inst):
|
||||
self.func = func
|
||||
self.inst = inst
|
||||
self.__name__ = self.func.__name__
|
||||
|
||||
def __call__(self, *args, **kw):
|
||||
return apply(self.func, (self.inst,) + args, kw)
|
||||
|
||||
class MetaHelper:
|
||||
|
||||
__methodwrapper__ = MetaMethodWrapper # For derived helpers to override
|
||||
|
||||
def __helperinit__(self, formalclass):
|
||||
self.__formalclass__ = formalclass
|
||||
|
||||
def __getattr__(self, name):
|
||||
# Invoked for any attr not in the instance's __dict__
|
||||
try:
|
||||
raw = self.__formalclass__.__getattr__(name)
|
||||
except AttributeError:
|
||||
try:
|
||||
_getattr_ = self.__dict__['_getattr_']
|
||||
except KeyError:
|
||||
raise AttributeError, name
|
||||
return _getattr_(name)
|
||||
if type(raw) != types.FunctionType:
|
||||
return raw
|
||||
return self.__methodwrapper__(raw, self)
|
||||
|
||||
class MetaClass:
|
||||
|
||||
"""A generic metaclass.
|
||||
|
||||
This can be subclassed to implement various kinds of meta-behavior.
|
||||
|
||||
"""
|
||||
|
||||
__helper__ = MetaHelper # For derived metaclasses to override
|
||||
|
||||
__inited = 0
|
||||
|
||||
def __init__(self, name, bases, dict):
|
||||
if dict.has_key('__getattr__'):
|
||||
raise TypeError, "Can't override __getattr__; use _getattr_"
|
||||
self.__name__ = name
|
||||
self.__bases__ = bases
|
||||
self.__realdict__ = dict
|
||||
self.__inited = 1
|
||||
|
||||
def __getattr__(self, name):
|
||||
try:
|
||||
return self.__realdict__[name]
|
||||
except KeyError:
|
||||
for base in self.__bases__:
|
||||
try:
|
||||
return base.__getattr__(name)
|
||||
except AttributeError:
|
||||
pass
|
||||
raise AttributeError, name
|
||||
|
||||
def __setattr__(self, name, value):
|
||||
if not self.__inited:
|
||||
self.__dict__[name] = value
|
||||
else:
|
||||
self.__realdict__[name] = value
|
||||
|
||||
def __call__(self, *args, **kw):
|
||||
inst = self.__helper__()
|
||||
inst.__helperinit__(self)
|
||||
try:
|
||||
init = inst.__getattr__('__init__')
|
||||
except AttributeError:
|
||||
init = lambda: None
|
||||
apply(init, args, kw)
|
||||
return inst
|
||||
|
||||
|
||||
Meta = MetaClass('Meta', (), {})
|
||||
|
||||
|
||||
def _test():
|
||||
class C(Meta):
|
||||
def __init__(self, *args):
|
||||
print "__init__, args =", args
|
||||
def m1(self, x):
|
||||
print "m1(x=%s)" %`x`
|
||||
print C
|
||||
x = C()
|
||||
print x
|
||||
x.m1(12)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
_test()
|
||||
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue