It would help if you showed the error that you're getting. However, I can take a guess...
Decorating a method of a class is hard. How is connectAndDisconnect
supposed to know what self
should be? connectAndDisconnect
is a static method of the base class, which gets called when the derived class gets created, long before any instances of the derived class get created.
There's a trick which lets the decorator figure out what self
should be, but it's a complicated hack and fragile in a way that I'll explain at the end. The trick is, use a class as the decorator, and make that class an descriptor (i.e. define __get__
) to give you a chance to determine what self
should be. In your case it would look something like:
class DABase(object):
def __init__(self):
self.__cursor = None
class connectAndDisconnect(object):
def __init__(self, method):
self._method = method # method is the thing being decorated
# note that it's an *unbound* method
self._instance = None # no way to know what the instance is yet
def __get__(self, instance, owner):
'This will be called when the decorated method is accessed'
self._instance = instance
return self
def __call__(self, *args):
'This is where the actual decoration takes place'
returnValue = None
# 'self' is the connectAndDisconnect object. 'self._instance' is the decorated object.
self._instance.DBConnect()
try:
self._instance.__cursor = self._instance.db.cursor()
# Since self._method is unbound, we have to pass the instance explicitly
returnValue = self._method(self._instance, *args)
finally:
self._instance.desconectarDB()
return returnValue
The derived class is unchanged:
class DA_Row(DABase):
@DABase.connectAndDisconnect
def save(self):
# ...
Now DA_Row.save
is actually an instance of the connectAndDisconnect
class. If d
is a DA_Row
object and someone calls d.save()
, the first thing that happens is that connectAndDisconnect.__get__
gets called because someone tried to access d.save
. This sets the _instance
variable to equal d
. Then connectAndDisconnect.__call__
gets called and the actual decoration takes place.
This works, most of the time. But it's fragile. It only works if you call save
in the "normal" way, i.e. through an instance. If you try to do funny stuff like calling DA_Row.save(d)
instead, it won't work because connectAndDisconnect.__get__
won't be able to figure out what the instance should be.