设为首页 收藏本站
查看: 1092|回复: 0

[经验分享] Python学习_08_函数式编程

[复制链接]

尚未签到

发表于 2015-12-2 10:18:55 | 显示全部楼层 |阅读模式
  在python中,函数名也是一个变量,代表对一个函数内容的引用,意味着可以作为参数传入到其他函数中,根据这个特性,发散出装饰器、闭包等概念,并涉及到变量作用域等问题。
函数
  python中函数操作符为(),在任何需要调用函数的地方都需要在函数名后面加(),表示调用该函数,否则的话仅仅表示一个函数对象,当然可以保存这个对象,或者将该函数对象传入到其他函数中,以供延迟调用。
  函数的参数分为按顺序确定的位置参数、默认参数、非关键字可变长度参数、关键字可变长度参数。
  其中位置参数仅仅通过传入时的顺序来确定调用,并且如果没有任何默认参数的话,传入的参数数目必须和函数定义一致。python支持默认参数,将一些常用的参数初始化而避免重复写相同的参数。这两个都是常规函数的参数形式。另外一种非常规的参数就是参数的数目不一定,即可变长度的参数,这些参数可以是不带关键字的元组,或者是带关键字的字典。
  python中,参数传入规则可以表示如下:
  def myFunc([formal_args,] *args_tuple,**kw_dict)
  其中formal_args表示位置参数,包含可能有的默认参数,而*args_tuple则表示可变长度的非关键字参数,**kw_dict表示可变长度的关键字参数。
匿名函数 lambada
  匿名函数是python中对单行语句的特殊用法,用于简化一些简单函数。如
  fun add(x,y):
    return x+y
  可以用lambada x,y:x+y来表示,lambada之后,冒号之前的内容表示需要传入的参数,冒号之后的内容表示执行的单行语句。
  lambada可以被存储,以便之后调用,如 add = lambada x,y:x+y,可以调用为add(x,y)。
装饰器 decorator
  由于函数的本质是一个引用,所以对函数名可以进行传入、传出等和一般变量一样的操作,通过这个特性,可以设计一些装饰器,用以对函数做重复的通用操作。python中对装饰器有额外的语法支持:@,在函数的上方加入@decorator语句,即表示对该函数进行装饰调用。一个函数可以被多个装饰器装饰。装饰器的本质是函数,所以装饰器也支持参数传入。一个装饰器的例子:
  def log(func):
    def wrappedFunc():
        print ’The %s() is called!’ % func.__name__
        return fun()
    return wrappedFunc
  通过@log的方式使用装饰器:
  @log
def func():
    pass
  上述语句的含义是func=log(func),此时,func的内容会调用装饰器log,log函数最终会返回wrappedFunc函数对象,但是并没有调用该函数,当func()执行时真正调用wrappedFunc(),该函数首先打印一行调用日志,然后返回func()函数的调用,这里返回的调用,并不是func函数对象,所以在这里会真正执行func函数的实体。从而实现“装饰”的过程。
闭包 closure
  在python2.1之后,作用域规则变为静态作用域,内部函数可以正常引用外部的变量,这种内部函数引用外部作用域的变量的函数就被称为闭包:
  def counter(start_at = 0):
    count = start_at
    def incr():
        count += 1
        return count[0]
    return incr
  可以看到闭包的形式装饰器很像,区别是闭包传入的不一定是一个函数,只是对外部变量的引用,内部函数中也不一定需要执行传入的函数,可能做一些其他的工作。
  闭包和装饰器的一个例子:
  from time import time
def logged(when):
    def log(f,*args,**kargs):
        print ‘’’Called:
function: %s
args: %r
kargs: %r’’’ %(f,args,kargs)
    def pre_logged(f):
         def wrapped(*args,**kargs):
            log(f,*args,**kargs)
            return f(*args,**kargs)
        return wrapped
    def  post_logged(f):
        def wrapped(*args,**args):
             now = time()
             try:
                return f(*args,**kargs)
            finally:
                log(f,*args,**kargs)
                print “time delta: %s “ % (time()-now)
        return wrapped
    try:
        return {‘pre’: pre_logged,’post’:post_logged}[when]
    except KeyError,e:
        raise ValueError(e),’must be “pre” or “post” '
@logged(“post")
def hello(name):
    print “Hello,”,name
hello(“word!") 
偏函数
  通过引用functools 模块中的partial 可以引入偏函数,偏函数的概念就是对原本需要多个参数的函数确定其中一个参数而称为另一个函数:
  from operator import add
from functools import partial
add1 = partial(add,1)
  此时,add1(5) 就表示add(1,5)
作用域和globa语句
  python搜索一个标示符的时候,会先从局部变量开始搜索,如果没有找到,则从上一级搜索,直到没有找到而返回NameError
  通过globa关键字,可以将变量推出局部作用域,不通过上述查找过程,而直接引用一个已命名的全局变量。
生成器和yield语句
  生成器用yield语句生成迭代器,每个yield语句顺序地使其内容在next()方法中被调用:
  def simpleGen():
    yield 1
    yield 2
  此时,simpleGen()就是一个迭代器,simpleGen().next() = 1,simpleGen().next() = 2
  除了next()方法获得下一个值,还可以通过send方法来讲值送给生成器:
  def counter(start_at = 0):
    count = start_at
    while True:
        val = (yield count)
        if val is not None:
            count = val
        else :
             count += 1
  count = count(5)
  count.next() = 5;count.next() = 6;count.send(9) = 9; count.next() = 10; count.close() ;  count.next(): StopIteration 

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-146226-1-1.html 上篇帖子: python学习笔记十:异常 下篇帖子: 利用xlrd模块实现Python读取Excel文档
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表