diff options
author | Guido van Rossum <guido@python.org> | 1997-08-25 15:37:59 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 1997-08-25 15:37:59 (GMT) |
commit | 27e4aa316875b1e5ad7fd85f93707ddf4fdba063 (patch) | |
tree | 17c0e25dbcec051797235ca89bc7e0f5c3e486ee /Demo/metaclasses/Meta.py | |
parent | bff110f3f10027cf03457556e42af2d3d87d5e7f (diff) | |
download | cpython-27e4aa316875b1e5ad7fd85f93707ddf4fdba063.zip cpython-27e4aa316875b1e5ad7fd85f93707ddf4fdba063.tar.gz cpython-27e4aa316875b1e5ad7fd85f93707ddf4fdba063.tar.bz2 |
Arbitrary point checkpoint commit. Take no notice.
Diffstat (limited to 'Demo/metaclasses/Meta.py')
-rw-r--r-- | Demo/metaclasses/Meta.py | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/Demo/metaclasses/Meta.py b/Demo/metaclasses/Meta.py new file mode 100644 index 0000000..b63f781 --- /dev/null +++ b/Demo/metaclasses/Meta.py @@ -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() + + |