Use A Class Decorator To Implement Late-initialization
Solution 1:
Rather than trying to decorate the functions that require connections, use a property for getting the connection itself.
classMyClass(object):
def__init__(self):
self._conn = None @propertydefconn(self):
if self._conn isNone:
self._conn = ConnectToDatabase()
return self._conn
defdo_something1(self):
self.conn.do_something1()
defdo_something2(self):
self.conn.do_something2()
As for a straight decorator example, playing off F.J's answer:
defprerequisite(prerequisite_function, *pre_args, **pre_kwargs):
defwrapper(func):
defwrapped(self, *args, **kwargs):
prerequisite_function(self, *pre_args, **pre_kwargs)
return func(self, *args, **kwargs)
return wrapped
return wrapper
classMyClass(object):
def__init__(self):
self.conn = Nonedefconnect(self):
if self.conn isNone:
self.conn = ConnectToDatabase()
@prerequisite(connect)defdo_something(self):
self.conn.do_something()
You could also make prerequisite
more robust by making it create descriptors so that it can behave correctly for functions and static methods as well as class and instance methods.
Solution 2:
I do like sr2222's approach of using a property for getting the connection, however here is an approach with decorators which may be useful or at least informative (use of functools.wraps()
is optional):
import functools
defrequire_connection(f):
@functools.wraps(f)defwrapped(self, *args, **kwargs):
self.connect()
return f(self, *args, **kwargs)
return wrapped
classMyClass(object):
def__init__(self):
self.conn = Nonedefconnect(self):
if self.conn : return
self.conn = ConnectToDatabase()
@require_connectiondefdo_something1(self):
self.conn.do_something1()
@require_connectiondefdo_something2(self):
self.conn.do_something2()
Solution 3:
Similar to sr2222's solution, but calling it what it is: a cached_property
.
The code is more compact, uses reusable building blocks, and in my opinion more readable.
classMyClass(object):@cached_propertydefconn(self):
return ConnectToDatabase()
defdo_something1(self):
self.conn.do_something1()
defdo_something2(self):
self.conn.do_something2()
The definition of cached_property
is found here.
Post a Comment for "Use A Class Decorator To Implement Late-initialization"