核心编程(第十章)嵌套函数,装饰器

例10.1

#!/usr/bin/env python
# encoding: utf-8
import ipdb


def safe_float(obj):
    'safe version of float()'
    try:
        retval = float(obj)
    except (ValueError, TypeError), diag:
        retval = str(diag)
    return retval


def main():
    'handles all the data processing'
    log = open('cardlog.txt', 'w')
    try:
        ccfile = open('carddata.txt', 'r')
    except IOError, e:
        log.write('no txns this month\n')
        log.close()
        return e

    txns = ccfile.readlines()
    ccfile.close()
    total = 0.00
    log.write('account log:\n')

    for eachTxn in txns:
        result = safe_float(eachTxn)
        if isinstance(result, float):
            total = total + result
            log.write('data... processed\n')
        else:
            log.write('ignored: %s' % result)
    print '$%.2f (new balance)' % (total)
    log.close()

if __name__ == "__main__":
    main()

11.3.6 装饰器

http://www.cnblogs.com/rollenholt/archive/2012/05/02/2479833.html

http://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html

下面的内容参考http://pythonmap.iteye.com/blog/1682696,加了部分我的理解

一、首先来大致了解下嵌套函数:

def foo(a):
    def subfoo(b):
        return(b + a)
    return(subfoo)

f = foo('content') #由于foo返回的是subfoo,所以f是对subfoo的引用
f('sub_') #因为subfoo记录了foo的参数变量'content',所以返回值为'sub_content'

实际上,这里的关系为:f == subfoo,a == 'cotent',b == 'sub_'

二、嵌套函数和它的变种(装饰器)

def action(z):
    return(z + 1)


def action_pro(y):
    def warpper(x):
        ipdb.set_trace()
        return(y(1) * x)
    return(warpper)

action2 = action_pro(action)  # action2一般和要装饰的函数一致,这里为了区分,这样写而已。
print action2(4)  # 此函数实际为warpper(4),返回值为8

这里,action2 == warpper, y == action(所以嵌套层用到y时,要有括号中的参数), x == 4

其实也等价于下面,action经过重新赋予,已经变为新的函数了:

def action(z):
    return(z + 1)


def action_pro(y):
    def warpper(x):
        ipdb.set_trace()
        return(y(1) * x)
    return(warpper)

action = action_pro(action)  # 第一个action为自定义的伪装变量,第二个action
print action(4)  # 此函数实际为warpper(4),返回值为8

使用@的写法,结果都是相同的:

def action_pro(y):
    def warpper(x):
        ipdb.set_trace()
        return(y(1) * x)
    return(warpper)


@action_pro
def action(z):
    return(z + 1)

 

posted @ 2016-05-17 21:36  ohmydenzi  阅读(163)  评论(0编辑  收藏  举报