将装饰器定义为类的一部分-问答-阿里云开发者社区-阿里云

开发者社区> 问答> 正文

将装饰器定义为类的一部分

2020-04-17 16:16:08 814 2

你想在类中定义装饰器,并将其作用在其他函数或方法上。

取消 提交回答
全部回答(2)
  • 景凌凯
    2020-04-17 17:42:44

    在类中定义装饰器初看上去好像很奇怪,但是在标准库中有很多这样的例子。 特别的,@property 装饰器实际上是一个类,它里面定义了三个方法 getter(), setter(), deleter() , 每一个方法都是一个装饰器。例如:

    class Person: # Create a property instance first_name = property()

    # Apply decorator methods
    @first_name.getter
    def first_name(self):
        return self._first_name
    
    @first_name.setter
    def first_name(self, value):
        if not isinstance(value, str):
            raise TypeError('Expected a string')
        self._first_name = value
    

    它为什么要这么定义的主要原因是各种不同的装饰器方法会在关联的 property 实例上操作它的状态。 因此,任何时候只要你碰到需要在装饰器中记录或绑定信息,那么这不失为一种可行方法。

    在类中定义装饰器有个难理解的地方就是对于额外参数 self 或 cls 的正确使用。 尽管最外层的装饰器函数比如 decorator1() 或 decorator2() 需要提供一个 self 或 cls 参数, 但是在两个装饰器内部被创建的 wrapper() 函数并不需要包含这个 self 参数。 你唯一需要这个参数是在你确实要访问包装器中这个实例的某些部分的时候。其他情况下都不用去管它。

    对于类里面定义的包装器还有一点比较难理解,就是在涉及到继承的时候。 例如,假设你想让在A中定义的装饰器作用在子类B中。你需要像下面这样写:

    class B(A): @A.decorator2 def bar(self): pass

    也就是说,装饰器要被定义成类方法并且你必须显式的使用父类名去调用它。 你不能使用 @B.decorator2 ,因为在方法定义时,这个类B还没有被创建。

    0 0
  • 哦哦喔
    2020-04-17 16:16:17
    在类里面定义装饰器很简单,但是你首先要确认它的使用方式。比如到底是作为一个实例方法还是类方法。 下面我们用例子来阐述它们的不同:
    
    from functools import wraps
    
    class A:
        # Decorator as an instance method
        def decorator1(self, func):
            @wraps(func)
            def wrapper(*args, **kwargs):
                print('Decorator 1')
                return func(*args, **kwargs)
            return wrapper
    
        # Decorator as a class method
        @classmethod
        def decorator2(cls, func):
            @wraps(func)
            def wrapper(*args, **kwargs):
                print('Decorator 2')
                return func(*args, **kwargs)
            return wrapper
    下面是一使用例子:
    
    # As an instance method
    a = A()
    @a.decorator1
    def spam():
        pass
    # As a class method
    @A.decorator2
    def grok():
        pass
    仔细观察可以发现一个是实例调用,一个是类调用。
    
    0 0
添加回答
相关问答

1

回答

业务场景建模问题定义中应该怎么面对系统?

2022-05-12 14:51:01 54浏览量 回答数 1

1

回答

在搭建时需自定义一部分代码,这些代码需要在什么操作后执行?

2022-05-10 18:51:24 35浏览量 回答数 1

1

回答

Java中number类的定义有哪些?

2022-04-03 14:26:31 674浏览量 回答数 1

1

回答

怎样定义类的作用域?

2021-10-24 22:27:47 85浏览量 回答数 1

1

回答

Java velocity 调用 POJO 类的属性时如何取值?

2021-10-13 14:17:57 309浏览量 回答数 1

1

回答

类和对象的定义及其关系是什么呢?

2021-09-30 14:51:20 175浏览量 回答数 1

1

回答

velocity 如何调用 POJO 类的属性?

2021-03-08 16:41:44 526浏览量 回答数 1

1

回答

如何定义开放应用模型?

2021-01-15 10:46:57 463浏览量 回答数 1

1

回答

已经在阿里云备案系统成功备案的网站,新增了域名,是否需要再做接入备案

2019-03-11 11:39:00 349浏览量 回答数 1

4

回答

如果是论坛类网站接入,是不是要先关站?

2013-05-29 15:24:23 5059浏览量 回答数 4
+关注
0
文章
446
问答
问答排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载