python装饰器

装饰器

装饰函数,扩展功能

装饰器作用

1.不修改函数的调用方式

2.给原来的函数添加新的功能

开发封闭原则

1.开发:对扩展开发

2.封闭:对修改封闭

示例

例1:计算代码运行时间

import time
def func():
    start_time = time.time()
    print('from the func')
    time.sleep(1)
    end_time = time.time()
    print(end_time - start_time)
func()

# 执行结果
from the func
1.0009381771087646

例2:计算函数运行时间

def timmer(f):
    start_time = time.time()
    f()
    end_time = time.time()
    print(end_time-start_time)

def func():
    print('from the func')
    time.sleep(1)
func()
timmer(func)  # 传入函数名就得到该函数的执行时间

 语法糖

import time
def timmer(func):
    def inner():
        start_time = time.time()
        func()
        end_time = time.time()
        print(end_time-start_time)
    return inner

@timmer  # 相当于func = timmer(func)
def func():  # 被装饰的函数
    print('from the func')
    time.sleep(1)
func()

 例3:带参数的装饰器

  1.在装饰器外面再加一层函数

  2.利用局部调用全局变量

  3.不需要装饰器时需改标识

import time
# flag = True
flag = False
def timmer_out(flag):
    def timmer(func):
        def inner(*args,**kwargs):
            if flag:
                start_time = time.time()
                ret = func(*args,**kwargs)
                end_time = time.time()
                print(end_time-start_time)
                return ret
            else:
                ret = func(*args, **kwargs)
                return ret
        return inner
    return timmer

# timmer = timmer_out(flag)
# @timmer
@timmer_out(flag)  
def func1():
    time.sleep(0.5)
    print('from func1')

@timmer_out(flag)
def func2():
    time.sleep(0.5)
    print('from func2')

func1()
func2()

例4:调用内置双下划线

from functools import wraps
def wrapper(func):
    @wraps(func)
    def inner(*args,**kwargs):
        print('在被装饰函数执行前动作')
        ret = func(*args,**kwargs)
        print('在被装饰函数执行后动作')
        return ret
    return inner

@wrapper  # holiday = wrapper()
def holiday(day):
    '''
    这是一个放假通知
    :param day: 
    :return: 
    '''
    print('放假时间%s'%day)
    return 'happy'

ret = holiday(3)
print(ret)
print(holiday.__name__)  # 查看函数名
print(holiday.__doc__)  # 查看注释

 类中方法

1.普通方法,没有任何参数,只能类来调用。

2.绑定方法:1)绑定到对象;2)绑定到类

3.静态方法:无论对象还是类都可以调用

class MyClass():
    # 普通方法
    def methoda():
        print("普通方法")
    # 绑定方法(绑定对象)
    def methodb(self):
        print("绑定到对象方法")
    # 绑定方法(绑定到类)
    @classmethod
    def methodc(cls):
        print(cls)
        print("绑定到类方法")
    # 静态方法
    @staticmethod
    def methodd(arg):
        print("静态方法")

# 实例化
obj = MyClass()
MyClass.methoda() # 普通方法
obj.methodb() # 绑定方法(绑定对象)
MyClass.methodb(111) # 绑定方法(绑定对象) 手动传参
MyClass.methodc() # 绑定方法(绑定到类)
obj.methodc() # 绑定方法(绑定到类)
obj.methodd(111) # 静态方法
MyClass.methodd(111) # 静态方法

# 默认在类外,动态添加动态方法
obj.func = lambda : print(123)
obj.func()

"""
执行结果:
----- 普通方法 绑定到对象方法 绑定到对象方法 <class '__main__.MyClass'> 绑定到类方法 <class '__main__.MyClass'> 绑定到类方法 静态方法 静态方法 123
"""

 property装饰器

可以把成员方法变成属性,控制成员的获取设置删除。

  @自定义.setter 设置

  @自定义.deleter 删除

写法一:

class MyClass():
    def __init__(self,name):
        self.name = name
    @property
    def username(self):
        return self.name
    @username.setter
    def username(self,val):
        self.name = val
    @username.deleter
    def username(self):
        del self.name

# 把username方法变成属性
obj = MyClass("test")
print(obj.username)

# 设置username
obj.username = "Python"
print(obj.username)

# 删除username
del obj.username

 

写法二:

class MyClass():
    def __init__(self,name):
        self.name = name
    @property
    def username(self):
        return self.name
    @username.setter
    def username(self,val):
        self.name = val
    @username.deleter
    def username(self):
        del self.name

# 把username方法变成属性
obj = MyClass("test")
print(obj.username)

# 设置username
obj.username = "Python"
print(obj.username)

# 删除username
del obj.username

 

posted @ 2019-08-10 16:49  wangzihong  阅读(160)  评论(0编辑  收藏  举报