days5

参考文档

http://egon09.blog.51cto.com/9161406/1836763

装饰器

''''
本质是函数
用来装饰其它函数(为其他函数添加附加功能)
原则:
1.不能修改被装饰函数的源代码
2.不能修改被装饰函数的调用方式

实现装饰器的知识储备
1.函数即'变量'
2.高阶函数
3.嵌套函数

高阶函数+嵌套函数=》装饰器

'''

准备姿势

import time


def timmer(func):
    def warpper(*args, **kwargs):
        start_time = time.time()
        func()
        stop_tome = time.time()
        print('the func run time is %s' % (stop_tome - start_time))

    return warpper


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

test1()

装饰器

函数调用顺序

函数调用顺序:其他高级语言类似,Python 不允许在函数未声明之前,对其进行引用或者调用

错误示范:
---------------------------------------------------
def foo():
    print 'in the foo'
    bar()

foo()

报错:
in the foo

Traceback (most recent call last):
  File "<pyshell#13>", line 1, in <module>
    foo()
  File "<pyshell#12>", line 3, in foo
    bar()
NameError: global name 'bar' is not defined

def foo():
    print 'foo'
    bar()
foo()
def bar():
    print 'bar'

报错:NameError: global name 'bar' is not defined
-----------------------------------------------------

正确示范:(注意,python为解释执行,函数foo在调用前已经声明了bar和foo,所以bar和foo无顺序之分)

--------------------------------------------------------
def bar():
    print 'in the bar'
def foo():
    print 'in the foo'
    bar()

foo()

def foo():
    print 'in the foo'
    bar()
def bar():
    print 'in the bar'
foo()
------------------------------------------------------

高阶函数

满足下列条件之一就可成函数为高阶函数
    1.把一函数当做参数传入另一个函数中(在不修改被装饰函数的情况下,为其添加功能)
    2.函数的返回值包含n个函数,n>0(不修改函数调用方式)
------------------------------------------------------
import time


def bar():
    time.sleep(3)
    print('in the bar!')


def test1(func):
    start_time = time.time()
    func()  # run bar
    stop_time = time.time()
    print('the run time of bar is %s' % (stop_time - start_time))


test1(bar)
----------------------------------------------

嵌套函数

内嵌函数和变量作用域:
定义:在一个函数体内创建另外一个函数,这种函数就叫内嵌函数(基于python支持静态嵌套域)
函数嵌套示范:
def foo():
    print('in the foo!')
    def bar():
        print('in the bar!')
    bar()

foo()

局部作用域和全局作用域的访问顺序
x=0
def grandpa():
    # x=1
    def dad():
        x=2
        def son():
            x=3
            print x
        son()
    dad()
grandpa()

局部变量修改对全局变量的影响
y=10
# def test():
#     y+=1
#     print y

def test():
    # global y
    y=2
    print y

test()
print y


def dad():
    m=1
    def son():
        n=2
        print '--->',m + n
    print '-->',m
    son()
dad()

闭包

如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是 closure

def counter(start_num=0):
    count=[start_num]
    def incr():
        count[0]+=1
        return count[0]
    return incr

print counter()
print counter()()
print counter()()
c=counter()
print c()
print c()

内嵌函数+高阶函数+闭包=》装饰器

预热两个范例:
范例一:函数参数固定
def decorartor(func):
    def wrapper(n):
        print 'starting'
        func(n)
        print 'stopping'
    return wrapper

 def test(n):
    print 'in the test arg is %s' %n

decorartor(test)('alex')

范例二:函数参数不固定
def decorartor(func):
    def wrapper(*args,**kwargs):
        print 'starting'
        func(*args,**kwargs)
        print 'stopping'
    return wrapper


def test(n,x=1):
    print 'in the test arg is %s' %n

decorartor(test)('alex',x=2)

无参装饰器

import time
def decorator(func):
        def wrapper(*args,**kwargs):
            start=time.time()
            func(*args,**kwargs)
            stop=time.time()
            print 'run time is %s ' %(stop-start)
            print timeout
        return wrapper

@decorator
def test(list_test):
    for i in list_test:
        time.sleep(0.1)
        print '-'*20,i


#decorator(test)(range(10)) 
test(range(10))

有参装饰器

import time
def timer(timeout=0):
    def decorator(func):
        def wrapper(*args,**kwargs):
            start=time.time()
            func(*args,**kwargs)
            stop=time.time()
            print 'run time is %s ' %(stop-start)
            print timeout
        return wrapper
    return decorator
@timer(2)
def test(list_test):
    for i in list_test:
        time.sleep(0.1)
        print '-'*20,i

#timer(timeout=10)(test)(range(10))
test(range(10))

装饰器应用案例

装饰器功能:函数超时则终止
# -*- coding: utf-8 -*-  
from threading import Thread  
import time  

class TimeoutException(Exception):  
    pass  

ThreadStop = Thread._Thread__stop#获取私有函数  

def timelimited(timeout):  
    def decorator(function):  
        def decorator2(*args,**kwargs):  
            class TimeLimited(Thread):  
                def __init__(self,_error= None,):  
                    Thread.__init__(self)  
                    self._error =  _error  

                def run(self):  
                    try:  
                        self.result = function(*args,**kwargs)  
                    except Exception,e:  
                        self._error =e  

                def _stop(self):  
                    if self.isAlive():  
                        ThreadStop(self)  

            t = TimeLimited()  
            t.start()  
            t.join(timeout)  

            if isinstance(t._error,TimeoutException):  
                t._stop()  
                raise TimeoutException('timeout for %s' % (repr(function)))  

            if t.isAlive():  
                t._stop()  
                raise TimeoutException('timeout for %s' % (repr(function)))  

            if t._error is None:  
                return t.result  

        return decorator2  
    return decorator  

@timelimited(2)  
def fn_1(secs):  
    time.sleep(secs)  
    return 'Finished'  

if __name__ == "__main__":  
    print fn_1(4)

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值