装饰器

python装饰器作用

python装饰器就是用于拓展原来函数功能的一种函数,这个函数的特殊之处在于它的返回值也是一个函数,使用python装饰器的好处就是在不用更改原函数的代码前提下给函数增加新的功能

完整的装饰器:

import time
def timmer(func):
    def deco():
        start_time=time.time()
        func()
        stop_time=time.time()
        print("in the func run  is %s" % (stop_time-start_time))
    return deco

@timmer #test1=timmer(test1)
def test1():
    time.sleep(3)
    print("in the test1")
@timmer #=test2=timmer(test2)
def test2():
    time.sleep(3)
    print("in the test2")
test1()
test2()


C:\Python34\python.exe C:/Users/Administrator/PycharmProjects/untitled25/lianxi.py
in the test1
in the func run  is 3.0001721382141113
in the test2
in the func run  is 3.00017094612121


自己编写的完整的装饰器


# -*- coding:UTF-8 -*-
import time
def timmer(func):
    def deco():
        func()
        print("welcome to beijing")
    return deco

@timmer #test1=timmer(test1)
def test1():
    time.sleep(3)
    print("in the test1")
@timmer #=test2=timmer(test2)
def test2():
    time.sleep(3)
    print("in the test2")
test1()
test2()


ssh://root@192.168.0.75:22/usr/bin/python -u /app/py_code/test3.py
in the test1
welcome to beijing
in the test2
welcome to beijing


传参数


import time
def timmer(func):
    def deco(name):
        start_time=time.time()
        func(name)
        stop_time=time.time()
        print("in the func run  is %s" % (stop_time-start_time))
    return deco

#@timmer #=test1=timmer(test1)
def test1():
    time.sleep(3)
    #print("in the test1")
@timmer #=test2=timmer(test2)
def test2(name):
    time.sleep(3)
    print("in the test2",name)
test1()
test2("bob")

C:\Python34\python.exe C:/Users/Administrator/PycharmProjects/untitled25/lianxi.py
in the test2 bob
in the func run  is 3.000170946121216


import time
def timmer(func):
    def deco(arg1,arg2):
        start_time=time.time()
        func(arg1,arg2)
        stop_time=time.time()
        print("in the func run  is %s" % (stop_time-start_time))
    return deco

#@timmer #=test1=timmer(test1)
def test1():
    time.sleep(3)
    #print("in the test1")
@timmer #=test2=timmer(test2)
def test2(name,age):
    time.sleep(3)
    print("in the test2",name,age)
test1()
test2("bob",25)



C:\Python34\python.exe C:/Users/Administrator/PycharmProjects/untitled25/lianxi.py
in the test2 bob 25
in the func run  is 3.000170946121216



通用型传递参数的装饰器

import time
def timmer(func):
    def deco(*args,**kwargs):
        start_time=time.time()
        func(*args,**kwargs)
        stop_time=time.time()
        print("in the func run  is %s" % (stop_time-start_time))
    return deco

#@timmer #=test1=timmer(test1)
def test1():
    time.sleep(3)
    #print("in the test1")
@timmer #=test2=timmer(test2)
def test2(name,age,high):
    time.sleep(3)
    print("in the test2",name,age,high)
test1()
test2("bob",25,170)


C:\Python34\python.exe C:/Users/Administrator/PycharmProjects/untitled25/lianxi.py
in the test2 bob 25 170
in the func run  is 3.0001721382141113


https://www.cnblogs.com/cicaday/p/python-decorator.html


基于类实现的装饰器:

装饰器要求接受一个callable对象,并返回一个callable对象(不太严谨,详见后文)。那么用类来实现也是也可以的。我们可以让类的构造函数__init__()接受一个函数,然后重载__call__()并返回一个函数,也可以达到装饰器函数的效果。


class logging(object):
    def __init__(self, func):
        self.func = func

    def __call__(self, *args, **kwargs):
        print ("[DEBUG]: enter function {func}()".format(
            func=self.func.__name__))
        return self.func(*args, **kwargs)
@logging
def say(something):
    print ("say {}!".format(something))
say('hello')



E:\python\python.exe E:/django工程/第20章/app01/cehi3.py
[DEBUG]: enter function say()
say hello!



自己改编的基于类实现的装饰器

# -*- coding:UTF-8 -*-
class logging(object):
    def __init__(self, func):
        self.func = func

    def __call__(self, *args, **kwargs):
        print ("[DEBUG]: enter function")
        return self.func(*args, **kwargs)
@logging
def say(something):
    print ("say",something)
say('hello')

ssh://root@192.168.0.75:22/usr/bin/python -u /app/py_code/test3.py
[DEBUG]: enter function
say hello


带参数的类装饰器
如果需要通过类形式实现带参数的装饰器,那么会比前面的例子稍微复杂一点。那么在构造函数里接受的就不是一个函数,而是传入的参数。通过类把这些参数保存起来。然后在重载__call__方法是就需要接受一个函数并返回一个函数。


class logging(object):
    def __init__(self, level='INFO'):
        self.level = level
        
    def __call__(self, func): # 接受函数
        def wrapper(*args, **kwargs):
            print "[{level}]: enter function {func}()".format(
                level=self.level,
                func=func.__name__)
            func(*args, **kwargs)
        return wrapper  #返回函数

@logging(level='INFO')
def say(something):
    print "say {}!".format(something)

E:\python\python.exe E:/django工程/第20章/app01/cehi3.py
[INFO]: enter function say()
say hello!



带参数的类装饰器--自己改编的

# -*- coding:UTF-8 -*-
class logging(object):
    def __init__(self, level='INFO'):
        self.level = level

    def __call__(self, func): # 接受函数
        def wrapper(*args, **kwargs):
            print ("[{level}]: enter function")
            func(*args, **kwargs)
        return wrapper  #返回函数

@logging(level='INFO')
def say(something):
    print ("say",something)
say('hello')

内置装饰器

python中@property装饰器的用法

参照:https://blog.csdn.net/wzqnls/article/details/53587049


不使用@property实现类

class Boy(object):
    def __init__(self, name):
        self.name = name

    def get_name(self):
        return self.name

    def set_name(self, new_name):
        self.name = new_name

    def del_name(self):
        del self.name
boy = Boy('Tom')
print(boy.get_name())



E:\python\python.exe E:/django工程/第20章/app01/cehi3.py
Tom
Alice

使用@property实现上述类

class Boy(object):
        def __init__(self, name):
            self._name = name

        @property
        def name(self):
            return self._name

        # 下面这个装饰器是由上面的@property衍生出来的装饰器
        @name.setter
        def name(self,new_name):
            self._name = new_name

        @name.deleter
        def name(self):

            del self._name
boy = Boy('Tom')
boy.name = 'white dog'
print(boy.name)
del boy.name

实例二:

class Animal(object):
    def __init__(self, name, age):
        self._name = name
        self._age = age
        self._color = 'Black'

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, value):
        self._name = value

    @property
    def age(self):
        return self._age

    @age.setter
    def age(self, value):
        if value > 0 and value < 100:
            self._age = value
        else:
            self._age = 0
            # print 'invalid age value.'

    @property
    def color(self):
        return self._color

    @color.setter
    def color(self, style):
        self._color = style


a = Animal('black dog', 3)
a.name = 'white dog'
a.age = 300
print ('Name:', a.name)
print ('Age:', a.age)
 

 

posted @ 2019-02-18 21:03  effortsing  阅读(148)  评论(0编辑  收藏  举报