1

I want to know where I am lagging. I am new to python decorators. How can we pass keyword arguments to decorator as parameter?

import time
import math

def deco(x,y,*args,**kwargs): #I want to pass kwarg like="andrew" here 
    def short(func):
        def longer(r,*args,**kwargs):
            print("before func exe")
            begin = time.time()
            func(r)
            end = time.time()
            print("after func exe")
            print("I am ",kwargs['like'])
            print("Total time taken in : ", func.__name__, end - begin)
        return longer
    return short

@deco(3,4,like="andrew")   
def greet(r):
    r = "I will be selelcted"
    print(r)
    # print("I am sorry for demanding")
    
print(greet('r'))

Here if we try to pass like="andrew" for **kwargs it throws error. how to pass it to deco then?

I also tried likes this.

def deco(x,y,like):
    def short(func):
def deco(x,y,'like'):
    def short(func):

What is the mistake I have done in above methods?

It throws error. KeyError: 'like'

shaila
  • 177
  • 2
  • 10
  • This might help: [Decorators with parameters](https://stackoverflow.com/questions/5929107/decorators-with-parameters) – sj95126 Nov 20 '21 at 04:58
  • Does this help? https://stackoverflow.com/questions/627501/how-can-i-use-named-arguments-in-a-decorator – manaclan Nov 20 '21 at 05:09

2 Answers2

1

You're accessing the kwargs['like'] in the wrong scope. It should be in the short() scope. Also, you don't need to print() the result of greet():

def deco(x,y,*args,**kwargs): #I want to pass kwarg like="andrew" here 
    def short(func):
        like = kwargs["like"]
        def longer(r,*args,**kwargs):
            print("before func exe")
            begin = time.time()
            func(r)
            end = time.time()
            print("after func exe")
            print("I am ",like)
            print("Total time taken in : ", func.__name__, end - begin)
        return longer
    return short

@deco(3,4,like="andrew")   
def greet(r):
    r = "I will be selelcted"
    print(r)
    # print("I am sorry for demanding")
    
greet('r')

That gives me:

➜  kwargs python main.py
before func exe
I will be selelcted
after func exe
I am  andrew
Total time taken in :  greet 7.3909759521484375e-06
djs
  • 3,947
  • 3
  • 14
  • 28
  • May I know Why is that "like" has to be accessed inside the short function when it belongs to deco function? Shouldnt we mention the keyword "like" inside deco(x,y,**kw)? Is that wrong? Please help. – shaila Nov 21 '21 at 04:38
  • That would be fine too. You just can't access it in the `longer()` function because you've redefined `kwargs` at that point. – djs Nov 21 '21 at 06:14
1

You can use decorator even inside class. use another function to pass arguments to decorator.

from pytube import YouTube

class term :
#use another function to pass arguments to decorator
    def show(x,like):
        def check(func): #function to be passed to decorate
            def parameters(self,u,v): #parameters inside function
                print(f"{like} likes no {x} for his jersey")
                func(self,u,v)
                print("Yes done")
            return parameters 
        return check
        
    x = 5
    @show(x,like = "andrew")
    def video1(self,u,v):
        video1 = YouTube(u).streams.first().download(v)
        return video1

u = input("Enter the video URL: ")
v = input("Enter the path: ")

t1 = term()
t1.video1(u,v)
print(t1)

OUTPUT:

Enter the video URL: https://www.youtube.com/watch?v=rUWxSEwctFU
Enter the path: E:\
andrew likes no 5 for his jersey
Yes done
Raju
  • 21
  • 2