V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
saximi
V2EX  ›  Python

请教关于类装饰器的问题

  •  
  •   saximi · 2017-08-20 23:52:32 +08:00 · 1795 次点击
    这是一个创建于 2670 天前的主题,其中的信息可能已经有所发展或是发生改变。

    1、下面是第一个类装饰器

    def decorator(cls):

        class Wrapper:
    
    	def __init__(self, *args):  
    		self.wrapped = cls(*args)
    
    	def __getattr__(self, name):  
    		return getattr(self.wrapped, name)
    
        return Wrapper
    

    @decorator

    class C:

        def __init__(self, x, y):  
    
    	self.attr = 'spam'
    

    2、下面是第二个类装饰器

    class Decorator:

        def __init__(self, C): 
    	self.C = C
    
        def __call__(self, *args): 
    	self.wrapped = self.C(*args)
    	return self
    
        def __getattr__(self, attrname): 
    	return getattr(self.wrapped, attrname)
    

    @Decorator

    class C: ...

    我看到书上说,第二个类装饰器和第一个不同,第二个没有能够处理给定的类的多个实例——每个实例创建调用都覆盖了前面保存的实例。第一个类装饰器却支持多个实例,因为每个实例创建调用产生了一个新的独立的包装器对象。

    请问怎么理解上面这段话,为何第二个类装饰器在每个实例创建时都会覆盖前面保存的实例呢? 感谢指点!

    7 条回复    2017-08-22 21:38:11 +08:00
    lolizeppelin
        1
    lolizeppelin  
       2017-08-21 09:43:50 +08:00
    去看描述器 看完再回来看你的问题
    lolizeppelin
        2
    lolizeppelin  
       2017-08-21 09:51:15 +08:00
    哦理解错,我以为是类里面的装饰器 ,你这是装饰类的装饰器

    这不很简单么第二个类装饰器可以预接参数成为实例,然后装饰类的时候是这个实例的 call 方法去套

    第一个是相当于把这个装饰器类实例化,初始化参数就是一个类


    装饰器就是套娃语法糖 func(func(func()))

    自己套一下就知道了
    saximi
        3
    saximi  
    OP
       2017-08-21 21:13:13 +08:00
    @lolizeppelin 谢谢,你写得话我基本能看明白,但是我还是无法和我的问题联系起来理解,第二个类装饰器是调用 Decorator.__call__方法,可这和“没有能够处理给定的类的多个实例——每个实例创建调用都覆盖了前面保存的实例”这句话有什么关系?
    saximi
        4
    saximi  
    OP
       2017-08-21 23:57:34 +08:00
    @lolizeppelin 我不知道要怎么理解这句话“没有能够处理给定的类的多个实例——每个实例创建调用都覆盖了前面保存的实例。” ,覆盖?怎么个覆盖法?
    lrxiao
        5
    lrxiao  
       2017-08-22 00:26:19 +08:00
    因为只是在调用一个 global 的 functor instance (
    saximi
        6
    saximi  
    OP
       2017-08-22 21:37:00 +08:00
    @lrxiao 您是说 self.C 是从外部传入的参数,所以可以看做是 global 的实例化方法,但是 cls 就是作用域在 wrapper 定义域内的实例化方法么?
    saximi
        7
    saximi  
    OP
       2017-08-22 21:38:11 +08:00
    @lrxiao 关于这个问题,我另外又发了个帖子,我觉得好像找到了存在矛盾的例子,能否指点,感谢!
    https://www.v2ex.com/t/384994#reply0
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3123 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 04:51 · PVG 12:51 · LAX 20:51 · JFK 23:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.