📜  Python中带参数的装饰器

📅  最后修改于: 2022-05-13 01:55:50.912000             🧑  作者: Mango

Python中带参数的装饰器

先决条件: Python中的装饰器,函数装饰器

我们知道装饰器是Python中一个非常强大和有用的工具,因为它允许程序员修改函数或类的行为。在本文中,我们将了解 在多个示例的帮助下带有参数的装饰器
Python函数是一等公民,这意味着函数可以像对待对象一样对待。

  • 可以将函数分配给变量,即可以引用它们。
  • 函数可以作为参数传递给另一个函数。
  • 函数可以从函数返回。

带参数的装饰器类似于普通的装饰器。

带参数的装饰器的语法:

@decorator(params)
def func_name():
    ''' Function implementation'''

上面的代码等价于

def func_name():
    ''' Function implementation'''

func_name = (decorator(params))(func_name)
"""

当执行从左到右开始时, decorator(params)被调用,它返回一个函数对象fun_obj 。使用 fun_obj 调用fun_obj(fun_name) 。在内部函数内部,执行所需的操作并返回实际的函数引用,该引用将分配给func_name 。现在, func_name()可用于调用应用了装饰器的函数。

带参数的装饰器是如何实现的

Python3
def decorators(*args, **kwargs):
    def inner(func):
        '''
           do operations with func
        '''
        return func
    return inner #this is the fun_obj mentioned in the above content
 
@decorators(params)
def func():
    """
         function implementation
    """


Python3
# Python code to illustrate
# Decorators basic in Python
 
def decorator_fun(func):
  print("Inside decorator")
 
  def inner(*args, **kwargs):
    print("Inside inner function")
    print("Decorated the function")
    # do operations with func
     
    func()
     
  return inner
 
@decorator_fun
def func_to():
    print("Inside actual function")
 
func_to()


Python3
# Python code to illustrate
# Decorators with parameters in Python
 
def decorator_fun(func):
  print("Inside decorator")
 
  def inner(*args, **kwargs):
    print("Inside inner function")
    print("Decorated the function")
     
    func()
     
  return inner
 
 
def func_to():
    print("Inside actual function")
 
# another way of using decorators
decorator_fun(func_to)()


Python3
# Python code to illustrate
# Decorators with parameters in Python
 
def decorator(*args, **kwargs):
    print("Inside decorator")
     
    def inner(func):
         
        # code functionality here
        print("Inside inner function")
        print("I like", kwargs['like'])
         
        func()
         
    # returning inner function   
    return inner
 
@decorator(like = "geeksforgeeks")
def my_func():
    print("Inside actual function")


Python3
# Python code to illustrate
# Decorators with parameters in Python
 
def decorator_func(x, y):
 
    def Inner(func):
 
        def wrapper(*args, **kwargs):
            print("I like Geeksforgeeks")
            print("Summation of values - {}".format(x+y) )
 
            func(*args, **kwargs)
             
        return wrapper
    return Inner
 
 
# Not using decorator
def my_fun(*args):
    for ele in args:
        print(ele)
 
# another way of using decorators
decorator_func(12, 15)(my_fun)('Geeks', 'for', 'Geeks')


Python3
# Python code to illustrate
# Decorators with parameters in Python  (Multi-level Decorators)
 
 
def decodecorator(dataType, message1, message2):
    def decorator(fun):
        print(message1)
        def wrapper(*args, **kwargs):
            print(message2)
            if all([type(arg) == dataType for arg in args]):
                return fun(*args, **kwargs)
            return "Invalid Input"
        return wrapper
    return decorator
 
 
@decodecorator(str, "Decorator for 'stringJoin'", "stringJoin started ...")
def stringJoin(*args):
    st = ''
    for i in args:
        st += i
    return st
 
 
@decodecorator(int, "Decorator for 'summation'\n", "summation started ...")
def summation(*args):
    summ = 0
    for arg in args:
        summ += arg
    return summ
 
 
print(stringJoin("I ", 'like ', "Geeks", 'for', "geeks"))
print()
print(summation(19, 2, 8, 533, 67, 981, 119))


这里的params也可以为空。

首先观察这些:

Python3

# Python code to illustrate
# Decorators basic in Python
 
def decorator_fun(func):
  print("Inside decorator")
 
  def inner(*args, **kwargs):
    print("Inside inner function")
    print("Decorated the function")
    # do operations with func
     
    func()
     
  return inner
 
@decorator_fun
def func_to():
    print("Inside actual function")
 
func_to()

其他方式:

Python3

# Python code to illustrate
# Decorators with parameters in Python
 
def decorator_fun(func):
  print("Inside decorator")
 
  def inner(*args, **kwargs):
    print("Inside inner function")
    print("Decorated the function")
     
    func()
     
  return inner
 
 
def func_to():
    print("Inside actual function")
 
# another way of using decorators
decorator_fun(func_to)()

输出:

Inside decorator
Inside inner function
Decorated the function
Inside actual function


让我们来看另一个例子:

示例 #1:

Python3

# Python code to illustrate
# Decorators with parameters in Python
 
def decorator(*args, **kwargs):
    print("Inside decorator")
     
    def inner(func):
         
        # code functionality here
        print("Inside inner function")
        print("I like", kwargs['like'])
         
        func()
         
    # returning inner function   
    return inner
 
@decorator(like = "geeksforgeeks")
def my_func():
    print("Inside actual function")

输出:

Inside decorator
Inside inner function
I like geeksforgeeks
Inside actual function

示例 #2:

Python3

# Python code to illustrate
# Decorators with parameters in Python
 
def decorator_func(x, y):
 
    def Inner(func):
 
        def wrapper(*args, **kwargs):
            print("I like Geeksforgeeks")
            print("Summation of values - {}".format(x+y) )
 
            func(*args, **kwargs)
             
        return wrapper
    return Inner
 
 
# Not using decorator
def my_fun(*args):
    for ele in args:
        print(ele)
 
# another way of using decorators
decorator_func(12, 15)(my_fun)('Geeks', 'for', 'Geeks')

输出:

I like Geeksforgeeks
Summation of values - 27
Geeks
for
Geeks

这个例子还告诉我们,外部函数参数可以被封闭的内部函数访问。

示例#3:

Python3

# Python code to illustrate
# Decorators with parameters in Python  (Multi-level Decorators)
 
 
def decodecorator(dataType, message1, message2):
    def decorator(fun):
        print(message1)
        def wrapper(*args, **kwargs):
            print(message2)
            if all([type(arg) == dataType for arg in args]):
                return fun(*args, **kwargs)
            return "Invalid Input"
        return wrapper
    return decorator
 
 
@decodecorator(str, "Decorator for 'stringJoin'", "stringJoin started ...")
def stringJoin(*args):
    st = ''
    for i in args:
        st += i
    return st
 
 
@decodecorator(int, "Decorator for 'summation'\n", "summation started ...")
def summation(*args):
    summ = 0
    for arg in args:
        summ += arg
    return summ
 
 
print(stringJoin("I ", 'like ', "Geeks", 'for', "geeks"))
print()
print(summation(19, 2, 8, 533, 67, 981, 119))

输出:

Decorator for 'stringJoin'
Decorator for 'summation'

stringJoin started ...
I like Geeksforgeeks

summation started ...
1729

1.装饰器内部

内部装饰器-python

2.函数内部

内部函数装饰器 python

注意:图像快照是使用 PythonTutor 拍摄的。