2

I've got a decorator function I'm applying to functions within a class. The decorator is supposed to do a check against an _api member variable. However, I get a global name 'self' is not defined error when I try to do this. What's the right way?

def requires_api(fn):
    def wrapped(*args, **kwargs):
        if self._api is not None:
            return fn(*args, **kwargs)
        else:
            return None
    return wrapped


@requires_api       
def do_something(self):
...
Yarin
  • 173,523
  • 149
  • 402
  • 512

2 Answers2

5

The reference to your instance is in your wrapper function's *args so the name self isn't avaialble. Use args[0], or just rewrite it as:

def wrapper(self, *args, **kwargs):
    # ...

Naturally, if you do this, your call through to the wrapped function should also include self.

kindall
  • 178,883
  • 35
  • 278
  • 309
1

Change

if self._api is not None:

to

if hasattr(args[0], '_api'):

args[0] has self. hasattr is the right way to check for an attribute.

If you try to access an attribute that does not exist, (if self._api does not exist) you will generate an AttributeError.

Joel Cornett
  • 24,192
  • 9
  • 66
  • 88
Steven Rumbalski
  • 44,786
  • 9
  • 89
  • 119