【问题标题】:Python: program to get the real name of decorated functionPython:获取装饰函数真实名称的程序
【发布时间】:2017-05-26 08:31:42
【问题描述】:

我想写一个装饰器来显示被装饰函数的真实名称,但是这样写就出错了。

from functools import update_wrapper

def decorator(d):
    def _decorator(f):
        update_wrapper(d(f), f)
        return d(f)
    return _decorator

@decorator
def add2(f):
    def _add2(x,y):
        return f(x,y)*2
    return _add2

@add2
def add(x,y): return x+y

如果我想得到add(x,y)的名字,显示如下:

>>>print add.__name__
_add2

但是如果我像这样对 func 装饰器做一点改动:

def decorator(d):
    def _decorator(f):
        return update_wrapper(d(f), f)
    return _decorator

结果将是正确的:

>>>print add.__name__
add

我真的很困惑。在我看来,这不应该有这样的区别,因为它们几乎是一样的。

【问题讨论】:

  • 我不确定我是否完全理解这个问题。 “为什么 functools.update_wrapper 保持我的函数名称不变,而我的自制装饰器却没有?”准确的措辞?
  • @KlausD.: update_wrapper()wraps.. 的底层实现。
  • @ymbirtt: update_wrapper() 用于'def decorator(d)' 的两个版本,但它们的写法不同,但在后来的版本中,保留我的函数名称似乎没用不变。这正是我想知道的
  • 对不起,这对我来说并没有真正澄清任何事情。你想在这里实现什么?你尝试了什么?你为什么这么做?发生了什么?你预计会发生什么?

标签: python decorator python-decorators


【解决方案1】:

你调用d(f)两次,每次都会创建一个新的包装函数对象;这些是独立的新副本。您只需将update_wrapper() 应用于第一个结果并返回第二个结果。

调用它一次

def decorator(d):
    def _decorator(f):
        wrapper = d(f)
        update_wrapper(wrapper, f)
        return wrapper
    return _decorator

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-20
    • 1970-01-01
    • 2020-12-18
    • 2023-01-21
    • 1970-01-01
    • 2018-10-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多