装饰器和闭包

装饰器和闭包

作用域

LEGB: L > E > G > B

L: local函数内部作用域
E: enclosing函数内部与内嵌函数之间
G: global 全局作用域
B: build-in 内置作用域

示例1:

passline = 60

#1 def func(val):
    if val >= passline:
        print "pass"
    else:
    print "failed"

#2 def func(val):
    passline = 90
    if val >= passline:
        print "pass"
    else:
    print "failed"
    
    def in_func():
        print val
    in_func()
    
def max(val1, val2):
    return Max(val1,val2)
    
 func(89)
 print max(90,200)

闭包概念:Closure,内部函数中对enclosing作用域的变量进行引用

函数实质与属性:

1.函数是一个对象

2.函数属性

3.函数返回值

4.函数执行完成后内部变量回收

    passline = 60
    def func(val):
    print "%x" %(val)
        passline = 90
        if val >= passline:
            print "pass"
        else:
        print "failed"
        
        def in_func():
            print val
        in_func()
        return in_func
    f = func(90)
    f()
    print f.__closure__

语法糖 @deco 装饰器是在模块加载时候运行。要调用的函数是在运行时候运行。

def deco(func):
    def in_deco():
        print ('in deco')
        func()
    print "call deco"
    
    return in_deco

@deco
def bar():
    print "XXxx"


######################## 

不带参数的装饰器

def log(func):
    def wrap(*args,**kw):
        print "before call func"
        func(*args, **kw)
        
    return wrap
    
    
@log
def echo():
    print "echo"
    
######################## 
带参数的装饰器

def log(text):
    def decorator(func):
        def wrap(*args, **kw):
            print '%s %s():' % (text, func.__name__)
            return func(*args, **kw)
        return wrapper
    return decorator
    
@log('execute')
def now():
    print '2013-12-25'
    
 ######################## 
 
    import functools

    def log(func):
        @functools.wraps(func)
        def wrapper(*args, **kw):
            print 'call %s():' % func.__name__
            return func(*args, **kw)
        return wrapper
        
 
 ######################## 
 
import functools

def log(text):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kw):
            print '%s %s():' % (text, func.__name__)
            return func(*args, **kw)
        return wrapper
    return decorator
    
######################## 
promos = []
def promotion(promo_func):
    promos.append(promo_func)
    return prono_func
    
@promotion
def fidelity(order):
    """为积分为1000或以上的顾客提供5%折扣"""
    return order.tital()* .05 if order.customer.fidlity >=1000 else 0
    
def bulk_item(order):
    """单个商品为20或以上的提供10%折扣"""
    discount = 0
    for item in oeder.cart:
        if items.quantity >= 20:
            discount += item.total() * .1
        return discount
        
def large_order(order):
    """订单中不同商品超过10个或以上时候提供7%折扣"""
    distinct_items = {item.product for item in order.cart}
    if len(distinct_items) >= 10:
        return order.total() * .07
    return 0
    
def best_promo(order):
    return max(promo(order) for promo in promos)
    
    
    
 >>> b =6
>>> def f(a):
...     print a
...     print b
...     b = 9
... 
>>> f(3)
3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in f
UnboundLocalError: local variable 'b' referenced before assignment

python编译函数的定义体时候,它判断b是局部变量,因为在函数中给它赋值了
这不是缺陷,而是设计选择:python不要求声明变量,但是假定在函数定义体中赋值的变量是局部变量。