Functools.update_wrapper() 无法正常工作
Posted
技术标签:
【中文标题】Functools.update_wrapper() 无法正常工作【英文标题】:Functools.update_wrapper() doesn't work properly 【发布时间】:2014-11-16 09:03:45 【问题描述】:我在装饰器中使用了Functools.update_wrapper()
,但似乎update_wrapper
只重写了函数属性(例如__doc__
、__name__
),但不影响help()
函数。
我知道these answers,但它们不适用于装饰器类。
这是我的功能。
import functools
class memoized(object):
def __init__(self, func):
self.func = func
functools.update_wrapper(self, func)
def __call__(self, *args):
self.func(*args)
@memoized
def printer(arg):
"This is my function"
print arg
这是输出
>>> printer.__doc__
This is my function
>>> help(printer)
Help on memoized in module __main__ object:
printer = class memoized(__builtin__.object)
| Methods defined here:
|
| __call__(self, *args)
|
| __init__(self, func)
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)
它看起来像一个错误,但我该如何修复它?
【问题讨论】:
【参考方案1】:functools.update_wrapper()
在实例上设置属性,但help()
查看关于类型的信息。
所以printer.__doc__
给你实例属性,help()
打印关于type(printer)
的信息,例如memoized
类,它没有 __doc__
属性。
这不是错误,这完全是设计使然; help()
will always look at the class when you pass in an instance。如果您希望 help()
为装饰函数工作,请不要使用类作为装饰器。
【讨论】:
那么,有没有办法修复它,只要我使用一个类作为装饰器? @user3664218:确实;help()
为您提供有关类的信息,而不是实例,如果您想要后者,则不应使用类装饰器。
@NeilG pydoc 源代码中的 cmets 很清楚:因为通常当您传入某个实例时,您通常希望记录可用的方法,而不是实例属性。那是正常的用例。 Pydoc 无法检测到该实例在此处被用作方法的替代品,这可能很不幸,但我不确定您是否会将其称为 broken。
我认为它被破坏了,因为使用类是一种标准方式,而我是实现装饰器的最通用方式。他们应该考虑的一种解决方法是使用默认为 type(self) if not isinstance(self, type) else self
的 __helpobject__
魔术方法,这将允许实现装饰器模式的类覆盖此方法。
@NeilG:使用类来装饰并不是所有的那个标准;大多数装饰器使用函数(带有闭包)。如果我需要在对象上实现自定义绑定行为或其他方法,我只会使用一个类。装饰器是 Python 中相对较晚的补充,Pydoc 是较旧的设置。如果这个问题足够人们关心,核心开发人员可能会想出一些东西。您可以通过讨论 Python-ideas 的想法或在 bugs.python.org 上提交问题来提供帮助。以上是关于Functools.update_wrapper() 无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章