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-conserv...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 'o****@xiludom.gro'.split('@')])"