OiO.lk Community platform!

Oio.lk is an excellent forum for developers, providing a wide range of resources, discussions, and support for those in the developer community. Join oio.lk today to connect with like-minded professionals, share insights, and stay updated on the latest trends and technologies in the development field.
  You need to log in or register to access the solved answers to this problem.
  • You have reached the maximum number of guest views allowed
  • Please register below to remove this limitation

Python decorators with class methods

  • Thread starter Thread starter Prasun Kumar Khan
  • Start date Start date
P

Prasun Kumar Khan

Guest
I want a decorator that I can use as both @decorator and decorator() with class methods, like this :

Code:
def decorator_with_args(name):
    print(f'Hello {name} !')
    def decorator(func):
        def wrapper(self, *args, **kwargs):
            print(f'Hello {self.title} {name} again !!')
            print(f"Calling {func.__name__} with instance {self}...")
            result = func(self, *args, **kwargs)
            print(f"{func.__name__} finished. Result: {result}")
            return result
        return wrapper
    return decorator

class Calculator:
    def __init__(self):
        self.title = 'Mr'

    @decorator_with_args('World')
    def add(self, a, b):
        return a + b

    def add2(self, a, b):
        return a + b

    def do_add(self, a, b):
        return decorator_with_args(f'World{a}')(self.add2)(self, a, b)

# Usage 1
calc = Calculator()
result = calc.add(3, 5)

# Usage 2
calc = Calculator()
result = calc.do_add(3, 5)

The reason why I want to use the decorator function as the above two representations is because:

  1. I want to use @decorator_with_args when the argument is known such as @decorator_with_args('World')
  2. I want to use decorator_with_args() when the argument is not known and I want the argument to be dynamic such as decorator_with_args(f'World{a}')

While @decorator_with_args works as expected [Usage 1], I get an error with decorator_with_args() [Usage 2]. I tried few things, but none of them worked for the latter.

If I try to pass (self, a, b), for example decorator_with_args(f'World{a}')(self.add2)(self, a, b), I get TypeError: add2() takes 3 positional arguments but 4 were given.

On the other hand, if I try to pass (a, b) without self, for example decorator_with_args(f'World{a}')(self.add2)(a, b), I get AttributeError: 'int' object has no attribute 'title'.

I appreciate there may exist other similar questions, which I tried to search but could not get them to work for my use case.
<p>I want a decorator that I can use as both @decorator and decorator() with class methods, like this :</p>
<pre><code>def decorator_with_args(name):
print(f'Hello {name} !')
def decorator(func):
def wrapper(self, *args, **kwargs):
print(f'Hello {self.title} {name} again !!')
print(f"Calling {func.__name__} with instance {self}...")
result = func(self, *args, **kwargs)
print(f"{func.__name__} finished. Result: {result}")
return result
return wrapper
return decorator

class Calculator:
def __init__(self):
self.title = 'Mr'

@decorator_with_args('World')
def add(self, a, b):
return a + b

def add2(self, a, b):
return a + b

def do_add(self, a, b):
return decorator_with_args(f'World{a}')(self.add2)(self, a, b)

# Usage 1
calc = Calculator()
result = calc.add(3, 5)

# Usage 2
calc = Calculator()
result = calc.do_add(3, 5)
</code></pre>
<p>The reason why I want to use the decorator function as the above two representations is because:</p>
<ol>
<li>I want to use @decorator_with_args when the argument is known such as @decorator_with_args('World')</li>
<li>I want to use decorator_with_args() when the argument is not known and I want the argument to be dynamic such as decorator_with_args(f'World{a}')</li>
</ol>
<p>While <code>@decorator_with_args</code> works as expected [Usage 1], I get an error with <code>decorator_with_args()</code> [Usage 2]. I tried few things, but none of them worked for the latter.</p>
<p>If I try to pass <code>(self, a, b)</code>, for example <code>decorator_with_args(f'World{a}')(self.add2)(self, a, b)</code>, I get <code>TypeError: add2() takes 3 positional arguments but 4 were given</code>.</p>
<p>On the other hand, if I try to pass <code>(a, b)</code> without <code>self</code>, for example <code>decorator_with_args(f'World{a}')(self.add2)(a, b)</code>, I get <code>AttributeError: 'int' object has no attribute 'title'</code>.</p>
<p>I appreciate there may exist other similar questions, which I tried to search but could not get them to work for my use case.</p>
 

Latest posts

M
Replies
0
Views
1
MusicLovingIndianGirl
M
Q
Replies
0
Views
1
quora question
Q
Top