The class object itself is only constructed after the body statements (all the statements inside the class <classname>(<bases,>): block have been executed. Decorators on the other hand are executed together with the function they are decorating.
You could just in the list you want methods to be added to, to your decorator:
class A(object):
methods = []
@dec(methods)
def a(self):
print 2
@dec(methods)
def a(self):
print 3
and have the decorator use that list to append your methods:
def dec(methodslist):
def decorator(f):
methodslist.append(f)
return f
return decorator
If you are using Python 3, then another option is for you to use a metaclass with a custom metaclass.__prepare__ class method that uses collections.defaultdict() to collect all attributes into lists first so you can still access them even if named the same. Your decorator then only needs to 'mark' each function object with an extra attribute or something. This is a little more involved.
When you then want to call those functions, you are right that they are not bound and won't have self passed in for you. Either manually pass in self, or bind the manually. Functions are descriptor objects, call their __get__ method to bind them to an instance:
for func in self.methods:
method = func.__get__(self)
method()
Demo:
>>> def dec(methodslist):
... def decorator(f):
... methodslist.append(f)
... return f
... return decorator
...
>>> class A(object):
... methods = []
... @dec(methods)
... def a(self):
... print 2
... @dec(methods)
... def a(self):
... print 3
... def call_all(self):
... for func in self.methods:
... method = func.__get__(self)
... method()
...
>>> A().call_all()
2
3