装饰器入门

文中部分内容参考:https://blog.csdn.net/trochiluses/article/details/21180733
装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。

  • 需求来源 ```python def foo(): print(‘in foo()’)

foo()

  1. 获取函数执行的时间
  2. ```python
  3. import time
  4. def foo():
  5. begin_time = time.time()
  6. print('in foo()')
  7. end_time = time.time()
  8. print("cost_time",end_time - begin_time)
  9. foo()

若按照该方法在具体函数中增加代码,当想查看其它函数比如foo2的执行时间时,就要将新增的代码拷贝至foo2,显然不可取

  • 以不变应万变 ```python import time def foo(): print(‘in foo()’)

def time_cost(func): begin_time = time.time() func() end_time = time.time() print(“cost_time”,end_time - begin_time)

time_cost(foo)

  1. 改造后,修改了调用部分的代码。原本我们是这样调用的:foo(),修改以后变成了:time_cost(foo)。这样的话,如果fooN处都被调用了,你就不得不去修改这N处的代码
  2. - **最大限度少改动**
  3. ```python
  4. import time
  5. def foo():
  6. print('in foo()')
  7. def time_cost(func):
  8. # 定义一个内嵌的包装函数,给传入的函数加上计时功能的包装
  9. def wrapper():
  10. begin_time = time.time()
  11. func()
  12. end_time = time.time()
  13. print("cost_time",end_time - begin_time)
  14. # 将包装后的函数返回
  15. return wrapper
  16. foo = time_cost(foo)
  17. foo()

这样,一个简易的计时器就做好了!我们只需要在定义foo以后调用foo之前,加上foo = time_cost(foo),就可以达到计时的目的,这也就是装饰器的概念

  • python语法糖
    1. @time_cost
    2. def foo():
    3. print('in foo()')
    4. # 等价于
    5. foo = time_code(foo)

    含参数装饰器

    ```python def time_cost(text): def decoracator(func):
    1. def wrapper():
    2. begin_time = time.time()
    3. func()
    4. end_time = time.time()
    5. print("cost_time and text",end_time - begin_time, text)
    6. return wrapper
    return decoracator

foo = time_cost(“test”)(foo)

foo()


<a name="PHxcS"></a>
# [@property](https://www.liaoxuefeng.com/wiki/1016959663602400/1017502538658208)
python的@property是python的一种装饰器,是用来修饰方法的。
<a name="OX1MI"></a>
## 作用:
我们可以使用@property装饰器来创建**只读属性**,@property装饰器会将**方法**转换为相同名称的**只读属性**,可以与所定义的属性配合使用,这样可以防止属性被修改。
<a name="aJGXn"></a>
## 使用场景:
<a name="BU8jK"></a>
### 1.修饰方法,使方法可以像属性一样访问。
```python
class DataSet(object):
    @property
    def method_with_property(self): ##含有@property
        return 15
    def method_without_property(self): ##不含@property
        return 15
l = DataSet()
print(l.method_with_property) # 加了@property后,可以用调用属性的形式来调用方法,后面不需要加()。
print(l.method_without_property())  #没有加@property , 必须使用正常的调用方法的形式,即在后面加()

2.与所定义的属性配合使用,这样可以防止属性被修改。

由于python进行属性的定义时,没办法设置私有属性,因此要通过@property的方法来进行设置。这样可以隐藏属性名,让用户进行使用的时候无法随意修改。

class Student(object):

    @property
    def birth(self):
        return self._birth

    @birth.setter
    def birth(self, value):
        self._birth = value

    @property
    def age(self):
        return 2015 - self._birth

@staticmethod

函数的静态方法。该方法不强制要求传递参数