bayerj wrote: > I want to make a registry of methods of a class during creation. My > attempt was this > > """ classdecorators.py > > Author: Justin Bayer > Creation Date: 2006-06-22 > Copyright (c) 2006 Chess Pattern Soft, > All rights reserved. """ > > class decorated(object): > > methods = [] > > @classmethod > def collect_methods(cls, method): > cls.methods.append(method.__name__) > return method > > class dec2(decorated): > > @collect_methods > def first_func(self): > pass > > @collect_methods > def second_func(self): > pass > > > def main(): > print dec2.methods > > if __name__ == '__main__': > main() > > This does not work and exits with "NameError: ("name 'collect_methods' > is not defined",)". Which is understandable due to the fact that the > class dec2 is not complete. > > Anyone can give me a hint how to work around this?
If you insist on doing black-magic (else go directly to the end of this post), here's a way to do it, based on Ian Bicking's __classinit__ recipe http://blog.ianbicking.org/a-conservative-metaclass.html (BTW, Ian, many many thanks for this trick - I really love it). class DeclarativeMeta(type): def __new__(meta, class_name, bases, new_attrs): cls = type.__new__(meta, class_name, bases, new_attrs) cls.__classinit__.im_func(cls, new_attrs) return cls class Declarative(object): __metaclass__ = DeclarativeMeta def __classinit__(cls, new_attrs): pass class MethodCollector(Declarative): def __classinit__(cls, new_attrs): cls.methods = [name for name, attr in new_attrs.items() \ if callable(attr)] class dec2(MethodCollector): def first_func(self): pass def second_func(self): pass If you want to choose which methods to collect, then it's just a matter of adding a simple decorator and a test in MethodCollector.__classinit__: def collect(func): func._collected = True return func class MethodCollector(Declarative): def __classinit__(cls, new_attrs): cls.methods = [name for name, attr in new_attrs.items() \ if callable(attr) \ and getattr(attr, '_collected', False)] class dec2(MethodCollector): @collect def first_func(self): pass @collect def second_func(self): pass def not_collected(self): pass *BUT* is it really useful to go thru all this mess ? class DeadSimple(object): @classmethod def methods(cls): return [name for name in dir(cls) \ if not name.startswith('__') \ and callable(getattr(cls, name))] My 2 cents... -- bruno desthuilliers python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for p in '[EMAIL PROTECTED]'.split('@')])" -- http://mail.python.org/mailman/listinfo/python-list