Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python decorator for accessing class variable

Tags:

python

I have a decorator to control time limit, if the function execution exceeds limit, an error is raised.

def timeout(seconds=10):
    def decorator(func):
        # a timeout decorator
    return decorator

And I want to build a class, using the constructor to pass the time limit into the class.

def myClass:
    def __init__(self,time_limit):
        self.time_limit = time_limit

    @timeout(self.time_limit)
    def do_something(self):
        #do something

But this does not work.

File "XX.py", line YY, in myClass
    @timeout(self.tlimit)
NameError: name 'self' is not defined

What's the correct way to implement this?

like image 503
MTANG Avatar asked Oct 29 '25 21:10

MTANG


1 Answers

self.time_limit is only available when a method in an instance of your class is called.

The decorator statement, prefixing the methods, on the other hand is run when the class body is parsed.

However, the inner part of your decorator, if it will always be applied to methods, will get self as its first parameter - and there you can simply make use of any instance attribute:

def timeout(**decorator_parms):
    def decorator(func):
        def wrapper(self, *args, **kwargs):
             time_limit = self.time_limit
             now = time.time()
             result = func(self, *args, **kwargs)
             # code to check timeout
             ..
             return result
        return wrapper
    return decorator

If your decorator is expected to work with other time limits than always self.limit you could always pass a string or other constant object, and check it inside the innermost decorator with a simple if statement. In case the timeout is a certain string or object, you use the instance attribute, otherwise you use the passed in value;

like image 99
jsbueno Avatar answered Nov 01 '25 10:11

jsbueno



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!