为了账号安全,请及时绑定邮箱和手机立即绑定

Python 3.5 装饰器和函数字段

Python 3.5 装饰器和函数字段

开心每一天1111 2021-11-09 19:57:22
我有以下代码片段:def wrapper(func):    def wrapped(*args, **kwargs):        func.var = 0        return func(*args, **kwargs)    return wrapped@wrapperdef f_out():    print(f_out.var)你能解释一下为什么跑步f_out()会加薪吗:AttributeError: 'function' object has no attribute 'var'编辑我不得不详细说明,因为答案给了我替代方案,但这不适用于我想要的情况。鉴于以下代码段:def wrapper(func):    def wrapped(*args, **kwargs):        func.var = 0        ret = func(*args, **kwargs)        print(func.var)    return wrapped@wrapperdef f_out():    f_out.var = 1f_out()print(f_out.var)我得到作为输出:01为什么会这样?
查看完整描述

3 回答

?
一只名叫tom的猫

TA贡献1906条经验 获得超3个赞

正确的方法是返回包装的函数并在返回之前更改它:


def wrapper(func):

    def wrapped(*args, **kwargs):

        return func(*args, **kwargs)

    wrapped.var = 0

    return wrapped


@wrapper

def f_out():

    print(f_out.var)

你正确地得到:


print(f_out())


0

更新的剪辑更改了var属性两次:


第一次在包装器中将原始函数的属性设置为 0 并在调用原始函数后打印它

然后,当从包装器调用原始函数时,它将引用 as 的函数f_out的属性设置为1。但在那一刻,引用 as 的函数f_out是被封装的函数,不再是原始函数。

因此,当您稍后打印时,f_out.var您将打印包装函数的属性,即 1。


这是一个稍微修改的代码来演示它:


def wrapper(func):

    def wrapped(*args, **kwargs):

        wrapped.orig = func          # keeps a ref to the original function

        func.var = 0

        ret = func(*args, **kwargs)

        print(func.var)

    return wrapped


@wrapper

def f_out():

    f_out.var = 1


f_out()

print(f_out.var, f_out.orig.var)

它打印


0

1 0


查看完整回答
反对 回复 2021-11-09
?
青春有我

TA贡献1784条经验 获得超8个赞

当您调用它时,装饰器正在包装您的函数。因此,当您调用f_out()它时,它会返回1. 您调用的是包装函数,而不是定义。


@wrapper

def f_out()

wrapper(f_out)当你调用它时相等 。


当您尝试打印时,f_out.var它会返回函数定义中的值。


查看完整回答
反对 回复 2021-11-09
?
小唯快跑啊

TA贡献1863条经验 获得超2个赞

return wrapped如果return func试试这个,你必须添加:


def wrapper(func):

    def wrapped(*args, **kwargs):

        func.var = 0

        return func(*args, **kwargs)

    return wrapped


@wrapper

def f_out():

    print(f_out.var)


查看完整回答
反对 回复 2021-11-09
  • 3 回答
  • 0 关注
  • 141 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信