函数式编程之函数返回值&装饰器

一、函数返回值

1.什么是函数返回值
顾名思义,函数返回值,就是一个函数的返回值,是一个函数名的情况
2.闭包
以计算多个数之和为例:
方法一:直接调用函数

def cacl_sum(*args):
    all_sum = 0
    for i in args:
        all_sum += i
    return all_sum
print cacl_sum(1,2,3,4,5)

运行效果:
15

方法二:采用闭包的方式

def lazy_sum(*args):
    def cacl_sum():
        all_sum = 0
        for i in args:
            all_sum += i
        return all_sum
    return cacl_sum
#调用lazy_sum(),得到返回值cacl_sum(是一个函数名)并赋给f
f = lazy_sum(1,2,3,4,5) 
#调用 cacl_sum 函数并运行
print f()              

注意: 当调用闭包 lazy_sum 时, 每次调用都返回一个新的函数。

f1 = lazy_sum(1,2,3,4,5)
f2 = lazy_sum(1,2,3,4,5)
print f1==f2
运行效果:
False

二、装饰器

1.什么是装饰器

  • 装饰器的本质

器,可以理解为函数,装饰器实质上是用来装饰函数的,装饰器就是在原来功能基础上加上一些其他功能,即在程序执行前或者执行后加上需要的操作。

  • 装饰器的功能

比如:权限的验证,日志记录, 函数运行时间统计, 执行函数前预备处理, 执行函数后清理
功能等。

2、装饰器的应用
<一>
背景:我们假设这么一个场景,某学生管理系统有不同的功能,我们想在每次执行一个功能的时候,都输出相同的欢迎语,我们当然可以分别在每个功能上添加这些欢迎的输出,但是当我们需要更改欢迎语的时候,是不是还得一一更改,那这样真的是太崩溃了,这个时候,装饰器就派上用场了

#装饰器
def addInfo(fun):
    def wrapped():
        print "欢迎使用XXX用户管理系统......"
        fun()
    return wrapped
# 装饰器的语法糖,
@addInfo
def login():
    print "login...."
    pass
@addInfo
def sign_in():
    print "sign in......"
    pass
@addInfo
def louout():
    print "logout......"
    pass
@addInfo
def Display_user_info():
    print "Display_user_info......"
    pass

login()
sign_in()
louout()
Display_user_info()

运行效果:
成功地为每一个功能模块都添加了欢迎信息,当我们需要对欢迎信息更改的时候,只需要更改该装饰器即可

欢迎使用XXX用户管理系统......
login....
欢迎使用XXX用户管理系统......
sign in......
欢迎使用XXX用户管理系统......
logout......
欢迎使用XXX用户管理系统......
Display_user_info......

那么,我么怎么理解装饰器的语法糖—-@addInfo呢???
以login()模块为例:
(1)当我们在调用login()的时候,先执行该模块的第一句@addInfo,实质就是将login()函数变为addInfo()函数的参数–(addInfo(login)),fun是形参,login是实参
(2)然后就执行addInfo()函数,该函数的返回值是一个函数名wrapped,
(3)所以接下来就执行函数wrapped()
(4)执行输出语句print后,顺序执行
(5)fun()就是在执行login()函数的内容,正如(1)所述fun是形参,login是实参

综上,调用login()实际上是指向函数wrapped
<二>函数计时器—–被装饰的函数有参数

import time   #导入time模块
def timer(fun):
    def wrapper(*args,**kwargs):   #参数类型为可变参数和关键字参数
        start_time = time.time()
        time1 = time.ctime()
        print "%s函数运行时间为%s" %(fun.__name__,time1)
        fun(*args,**kwargs)       #参数类型为可变参数和关键字参数
        end_time = time.time()
        time1 = end_time - start_time
        print "%s函数运行了%ss" %(fun.__name__,time1)
    return wrapper
@timer
def add(*a):
    print "结果为:%d" %(sum(a))
add(1,2,4,7,8)

运行效果:

add函数运行时间为Mon Jan 15 16:22:02 2018
结果为:22
add函数运行了5.79357147217e-05s

<三>装饰器带参数
装饰器带参数就需要在该装饰器外面再包裹一层函数,用来传参
代码:

def addInfo1(a):                   #a是形参
    def addInfo(fun):
        def wrapped():
            print "欢迎使用XXX用户管理系统%s页面......" %(a)
            fun()
        return wrapped
    return addInfo
# 装饰器的语法糖                   
@addInfo1("login")                 #login是实参
def login():
    print "login...."
    pass
@addInfo1("sign in")
def sign_in():
    print "sign in......"
    pass
@addInfo1("logout")
def louout():
    print "logout......"
    pass
@addInfo1("Display_user_info")
def Display_user_info():
    print "Display_user_info......"
    pass

login()
sign_in()
louout()
Display_user_info()

运行效果:

欢迎使用XXX用户管理系统login页面......
login....
欢迎使用XXX用户管理系统sign in页面......
sign in......
欢迎使用XXX用户管理系统logout页面......
logout......
欢迎使用XXX用户管理系统Display_user_info页面......
Display_user_info......

这里的执行和<一>类似,不同的就是,在执行addInfo()函数之前,先执行了addInfo1()函数传递了装饰器的参数,返回了函数名addInfo,然后执行addInfo()函数,接下来就与<一>无异

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值