Python学习之路-----装饰器(3)

修饰带参数的参数

    上两篇提到的装饰器的例子中,被修饰的函数没有参数,那么如果修饰带参数的装饰器又该如何书写呢?

#coding=utf-8

def f1(func):
    print('in f1')
    def f1_inner():
        print('in f1_inner')
        func()
    return f1_inner

@f1
def f(a,b):
    print('in f')

if __name__ == '__main__':
    a,b = 1,2
    f(a,b)

结果:
in f1
Traceback (most recent call last):
  File "E:/sourceInsightPro/python_code/16点14分/zhuangshiqi2.py", line 16, in <module>
    f(a,b)
TypeError: f_inner() takes 0 positional arguments but 2 were given

     首先f在定义是需要两个参数,因此在调用的时候传入两个参数,但是结果却报错,提示16行错误:f_inner()不需要位置参数却传给了两个参数。

     原因是装饰器f1修饰函数f,利用闭包的语句实现就是:f = f1(f),这句执行后f1返回的是f1_inner的引用,而f本身传入了两个参数,f1_inner在定义时却没有参数,因此才出现了这个错误,因此,在f1_inner定义时需要定义形参。即代码如下所示:

def f1(func):
    print('in f1')
    def f1_inner(a,b):
        print('in f1_inner')
        func()
    return f1_inner

@f1
def f(a,b):
    print('in f')

if __name__ == '__main__':
    a,b = 1,2
    f(a,b)



结果:
in f1
Traceback (most recent call last):
in f1_inner
  File "E:/sourceInsightPro/python_code/16点14分/zhuangshiqi2.py", line 16, in <module>
    f(a,b)
  File "E:/sourceInsightPro/python_code/16点14分/zhuangshiqi2.py", line 7, in f_inner
    func()
TypeError: f() missing 2 required positional arguments: 'a' and 'b'

     在f1_inner中加上形参后发现依旧报错,提示是第六行:函数f丢了两个位置参数

     原因是在调用函数f(a,b)后,f是作为实参传入f1中,但是在f1_inner中调用func(即f)时却没有传入参数,因此才出现了这样的错,修改后的完整代码如下:

#coding=utf-8

def f1(func):
    print('in f1')
    def f1_inner(a,b):
        print('in f1_inner,a:%d b:%d' % (a,b))
        func(a,b)
    return f1_inner

@f1
def f(a,b):
    print('in f')
    print('a:%d b:%d' % (a,b))

if __name__ == '__main__':
    a,b = 1,2
    f(a,b)



结果:
in f1
in f1_inner,a:1 b:2
in f
a:1 b:2

     至此实现了装饰器修饰带参数的函数。但是却引入一个问题:上面例子中f需要两个参数,因此在f1_inner定义时也声明了两个形参。但是这样的书写形式太麻烦,耦合性太大,能否换一种简便的书写形式呢?此时便可以使用之前函数中的学到的:*args和**kwargs。看下面的代码:

def f2(func):
    print('in f2')
    def f2_inner(*args,**kwargs):
        print('in f2_inner')
        print(args)
        print(kwargs)
        func(*args,**kwargs)
    return f2_inner

@f2
def f(a,b,*args,**kwargs):
    print('in f')
    print(a)
    print(b)
    print(args)
    print(kwargs)

if __name__ == '__main__':
    a,b = 1,2
    f(a,b,'hello','world',c = 10,d = 20)


结果:
in f2
in f2_inner
(1, 2, 'hello', 'world')
{'c': 10, 'd': 20}
in f
1
2
('hello', 'world')
{'c': 10, 'd': 20}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
学习Python装饰可以通过以下步骤进行: 1. 了解装饰的概念和作用:装饰是一种用于修改函数或类行为的函数或类。它可以在不修改原始函数或类的情况下,通过添加额外的功能来扩展其功能。 2. 学习装饰的语法:装饰可以使用函数或类来实现。使用函数实现装饰时,需要使用`@`符号将装饰应用于目标函数。使用类实现装饰时,需要在类中定义`__call__`方法,并将装饰应用于目标函数。 3. 掌握装饰的常见应用场景:装饰可以用于添加日志记录、性能统计、权限验证、缓存等功能。了解这些应用场景可以帮助你更好地理解装饰的实际用途。 4. 阅读相关文档和教程:有很多优秀的教程和文档可以帮助你深入学习Python装饰。你可以阅读Python官方文档中关于装饰的部分,也可以搜索一些优质的博客或教程来学习。 5. 实践编写装饰:通过编写一些简单的装饰来加深对装饰的理解。可以从一些简单的装饰开始,逐渐扩展到更复杂的装饰。 以下是一个使用类中的方法作为装饰的示例[^2]: ```python class Decorator: def __init__(self, func): self.func = func def __call__(self, *args, **kwargs): # 在函数执行前添加额外的功能 print("Before function execution") # 调用原始函数 result = self.func(*args, **kwargs) # 在函数执行后添加额外的功能 print("After function execution") return result @Decorator def target_function(): print("Inside target function") # 调用被装饰的函数 target_function() ``` 这个示例中,`Decorator`类定义了一个装饰,它在被装饰的函数执行前后添加了额外的功能。通过将`@Decorator`应用于`target_function`,`target_function`就被`Decorator`装饰修饰了。当调用`target_function`时,装饰的功能会被触发。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值