九歌当下 发表于 2023-3-5 14:00:30

含参函数如何使用装饰器


我先定义一个闭包
def logger(func):
    def call_func():
      print("----------")
      func()
      print("----------")
    return call_func

再给一个含参函数加上该闭包的装饰器
@logger
def sayhi(name):
    print("hi,{}".format(name))

然后函数sayhi()就没法用了
sayhi("小甲鱼")
Traceback (most recent call last):
File "<pyshell#38>", line 1, in <module>
    sayhi("小甲鱼")
TypeError: logger.<locals>.call_func() takes 0 positional arguments but 1 was given

求帮助{:10_266:}

isdkz 发表于 2023-3-5 14:10:07

一个函数在使用装饰器后会被替换成装饰器的返回值,

而装饰器的返回值 call_func 不接受任何参数,故而你给 sayhi 传参会报错,

所以就是要让 call_func 接收跟 sayhi 的参数个数一样的形参,并在 call_func 调用 sayhi 的时候把参数传递给 sayhi

故对你的代码修改如下:

def logger(func):
    def call_func(name):                         # 改了这里
      print("----------")
      func(name)                         # 改了这里
      print("----------")
    return call_func

@logger
def sayhi(name):
    print("hi,{}".format(name))

sayhi("小甲鱼")

九歌当下 发表于 2023-3-5 14:16:27

isdkz 发表于 2023-3-5 14:10
一个函数在使用装饰器后会被替换成装饰器的返回值,

而装饰器的返回值 call_func 不接受任何参数,故而 ...

OK, 谢谢了{:10_275:}

歌者文明清理员 发表于 2023-3-5 15:05:34

本帖最后由 歌者文明清理员 于 2023-3-5 16:41 编辑

def logger(func):
    def call_func(**args, **kwargs):                         # 改了这里
      print("----------")
      func(**args, **kwargs)                         # 改了这里
      print("----------")
    return call_func

@logger
def sayhi(name):
    print("hi,{}".format(name))

sayhi("小甲鱼")
这样就兼容所有函数了

九歌当下 发表于 2023-3-5 16:33:37

歌者文明清理员 发表于 2023-3-5 15:05
这样就兼容所有函数了

真是太厉害了,没有想到收集参数能这么用{:10_323:}

歌者文明清理员 发表于 2023-3-5 16:40:30

九歌当下 发表于 2023-3-5 16:33
真是太厉害了,没有想到收集参数能这么用

可惜了我的最佳答案{:10_266:}

九歌当下 发表于 2023-3-5 16:48:55

歌者文明清理员 发表于 2023-3-5 16:40
可惜了我的最佳答案

下次看了得晚点在设最佳答案{:10_262:}
页: [1]
查看完整版本: 含参函数如何使用装饰器