首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python中的高阶类

Python中的高阶类
EN

Stack Overflow用户
提问于 2013-11-26 22:41:06
回答 2查看 625关注 0票数 2

有人能解释一下为什么下面的代码不起作用吗?我试图让一个类装饰器来提供新的__repr____init__方法,如果我用它来修饰一个类,那么似乎只定义了repr方法。我设法修复了最初的问题,方法是让修饰器对原始类进行破坏性修改,而不是创建一个新类(例如,它定义了新方法,然后只使用cl.__init__ = __init__覆盖它们)。现在我只是好奇为什么基于子类的尝试不起作用。

代码语言:javascript
复制
def higherorderclass(cl):
    @functools.wraps(cl)
    class wrapped(cl):
        def __init__(self, *args, **kwds):
            print 'in wrapped init'
            super(wrapped, self).__init__(*args, **kwds)
        def __repr__(self):
            return 'in wrapped repr'
    return wrapped
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-11-26 22:47:18

第一个问题是您使用的是旧风格的类。(也就是说,不继承object、另一个内置类型或另一个新样式类的类。)在旧式类中,特殊方法查找的工作方式不同。实际上,您不想了解它是如何工作的,只需要使用新样式的类就行了。

但是接下来会遇到下一个问题:首先,functools.wraps不能在类上工作。使用新的样式类,您将得到某种类型的AttributeError;对于旧的类,事情只是在不同的方面默默地失败。您也不能只显式地使用update_wrapper。问题是,您正在尝试替换类的属性,这些属性是不可写的,而且没有(直接的)方法。

如果您使用新的样式类,并且不尝试使用wraps,那么一切都很好。

票数 4
EN

Stack Overflow用户

发布于 2013-11-26 22:49:09

删除@functools.wraps()装饰符,这只适用于函数装饰器。对于一个新样式的类,您的装饰器在以下方面失败:

代码语言:javascript
复制
>>> @higherorderclass
... class Foo(object):
...     def __init__(self):
...         print 'in foo init'
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "<stdin>", line 3, in higherorderclass
  File "/Users/mj/Development/Library/buildout.python/parts/opt/lib/python2.7/functools.py", line 33, in update_wrapper
    setattr(wrapper, attr, getattr(wrapped, attr))
AttributeError: attribute '__doc__' of 'type' objects is not writable

没有@functools.wraps()行,您的装饰器就能正常工作:

代码语言:javascript
复制
>>> def higherorderclass(cl):
...     class wrapped(cl):
...         def __init__(self, *args, **kwds):
...             print 'in wrapped init'
...             super(wrapped, self).__init__(*args, **kwds)
...         def __repr__(self):
...             return 'in wrapped repr'
...     return wrapped
... 
>>> @higherorderclass
... class Foo(object):
...     def __init__(self):
...         print 'in foo init'
... 
>>> Foo()
in wrapped init
in foo init
in wrapped repr
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20229532

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档