I have a class named Server which can be started and stopped. Certain methods should not be called unless the Server is started, in which case a NotConnectedException should be raised. Is there a way to call a method before every method in a class and determine if class variable _started is set to True?
I tried using a decorator, but the decorator function does not have access to the class variable. I was trying to do something like this:
class Server(object):
_started = False
def started(self):
if(self._started == False):
raise NotConnectedException
@started
def doServerAction(self):
...
Remember what decorators are:
@decorate
def foo(...):
...
is exactly equivalent to:
def foo(...):
...
foo = decorate(foo)
The decorator is called on the function, so calling the first parameter self makes no sense. Also, the decorator is called on the function when it is defined, and whatever it returns is used in place of the function. So even if your started
decorator didn't throw an AttributeError
by trying to access the _started
attribute of a function, it would then return None
, making all your methods set to None
, and thus not even be callable.
What you want is something like this:
import functools
def started(func):
@functools.wraps(func)
def wrapper(self, *args, **kwargs):
if not self._started:
raise ...
else:
return func(self, *args, **kwargs)
return wrapper
Almost all decorators are of this form; they take a function, create a wrapper that does something "around" the received function, and then return the wrapper. The use of functools.wraps
here is a convenience if you ever end up working with this code in an interactive interpreter session; it automatically updates the wrapper
function with the name and docstring of the original function, which makes the decorated functions "look like" the original function a bit more.
It's irrelevant whether this is defined inside the class or not.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With