请教关于类装饰器的问题

2017-08-20 23:52:32 +08:00
 saximi

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: ...

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

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

1716 次点击
所在节点    Python
7 条回复
lolizeppelin
2017-08-21 09:43:50 +08:00
去看描述器 看完再回来看你的问题
lolizeppelin
2017-08-21 09:51:15 +08:00
哦理解错,我以为是类里面的装饰器 ,你这是装饰类的装饰器

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

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


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

自己套一下就知道了
saximi
2017-08-21 21:13:13 +08:00
@lolizeppelin 谢谢,你写得话我基本能看明白,但是我还是无法和我的问题联系起来理解,第二个类装饰器是调用 Decorator.__call__方法,可这和“没有能够处理给定的类的多个实例——每个实例创建调用都覆盖了前面保存的实例”这句话有什么关系?
saximi
2017-08-21 23:57:34 +08:00
@lolizeppelin 我不知道要怎么理解这句话“没有能够处理给定的类的多个实例——每个实例创建调用都覆盖了前面保存的实例。” ,覆盖?怎么个覆盖法?
lrxiao
2017-08-22 00:26:19 +08:00
因为只是在调用一个 global 的 functor instance (
saximi
2017-08-22 21:37:00 +08:00
@lrxiao 您是说 self.C 是从外部传入的参数,所以可以看做是 global 的实例化方法,但是 cls 就是作用域在 wrapper 定义域内的实例化方法么?
saximi
2017-08-22 21:38:11 +08:00
@lrxiao 关于这个问题,我另外又发了个帖子,我觉得好像找到了存在矛盾的例子,能否指点,感谢!
https://www.v2ex.com/t/384994#reply0

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/384418

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX