在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 

Python学习_08_函数式编程的更多相关文章

  1. Python学习--08函数式编程

    函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数. 高阶函数 Python支持高阶函数(Higher-order function). 什么是高阶函数呢?把函数作为参 ...

  2. Python学习:函数式编程(lambda, map() ,reduce() ,filter())

    1. lambda: Python 支持用lambda对简单的功能定义“行内函数” 2.map() : 3.reduce() : 4.filter() : map() ,reduce() , filt ...

  3. Python进阶:函数式编程实例(附代码)

    Python进阶:函数式编程实例(附代码) 上篇文章"几个小例子告诉你, 一行Python代码能干哪些事 -- 知乎专栏"中用到了一些列表解析.生成器.map.filter.lam ...

  4. Python Decorator 和函数式编程

    看到一篇翻译不错的文章,原文链接: Python Decorator 和函数式编程

  5. Python基础:函数式编程

    一.概述 Python是一门多范式的编程语言,它同时支持过程式.面向对象和函数式的编程范式.因此,在Python中提供了很多符合 函数式编程 风格的特性和工具. 以下是对 Python中的函数式编程 ...

  6. python学习_数据处理编程实例(二)

    在上一节python学习_数据处理编程实例(二)的基础上数据发生了变化,文件中除了学生的成绩外,新增了学生姓名和出生年月的信息,因此将要成变成:分别根据姓名输出每个学生的无重复的前三个最好成绩和出生年 ...

  7. 可爱的 Python : Python中的函数式编程,第三部分

    英文原文:Charming Python: Functional programming in Python, Part 3,翻译:开源中国 摘要:  作者David Mertz在其文章<可爱的 ...

  8. Python进阶之函数式编程(把函数作为参数)

    什么是函数式编程? 什么是函数式编程? 函数:function 函数式:functional,一种编程范式 函数式编程是一种抽象计算的编程模式 函数≠函数式,比如:计算≠计算机 在计算机当中,计算机硬 ...

  9. Python之面向对象函数式编程

    Python之面向对象函数式编程 函数式编程的根本就是用 def 去模拟数学式的编程逻辑. 类似与 y = 2*x + 1 ,当x = 3 时,函数的结果y就得7. def test(x): retu ...

随机推荐

  1. FastDFS教程IV-文件服务器集群搭建

    1.简介     本文主要介绍FastDFS文件服务器的集群搭建,在阅读本文之前,您需具备FastDFS文件服务器单节点安装,扩容,迁移等方面的知识.同时,您还需了解Keepalived,nginx方 ...

  2. C++反汇编第六讲,认识C++中的Try catch语法,以及在反汇编中还原

    C++反汇编第六讲,认识C++中的Try catch语法,以及在反汇编中还原 我们以前讲SEH异常处理的时候已经说过了,C++中的Try catch语法只不过是对SEH做了一个封装. 如果不懂SEH异 ...

  3. Android HandlerThread 源码分析

    HandlerThread 简介: 我们知道Thread线程是一次性消费品,当Thread线程执行完一个耗时的任务之后,线程就会被自动销毁了.如果此时我又有一 个耗时任务需要执行,我们不得不重新创建线 ...

  4. python爬虫(四)_urllib2库的基本使用

    本篇我们将开始学习如何进行网页抓取,更多内容请参考:python学习指南 urllib2库的基本使用 所谓网页抓取,就是把URL地址中指定的网络资源从网络流中读取出来,保存到本地.在Python中有很 ...

  5. linux下分析Java程序内存汇总

    使用pmap查看进程内存 执行命令 使用pmap能够查看某一个进程(非java的也能够)的内存使用使用情况, 命令格式: pmap 进程id 演示样例说明 比如执行: pmap 12358 显示结果例 ...

  6. hibernate5(9)注解映射[1]多对一单向关联

    在博客站点中,我们可能须要从某一篇文章找到其所关联的作者.这就须要从文章方建立起对用户的关联,即是多对一的映射关系. 如今先看一个配置实例:我们的文章实体类 package com.zeng.mode ...

  7. 微服务架构之RPC-client序列化细节

    通过上篇文章的介绍,知道了要实施微服务,首先要搞定RPC框架,RPC框架的职责要向[调用方]和[服务提供方]屏蔽各种复杂性: (1)让调用方感觉就像调用本地函数一样 (2)让服务提供方感觉就像实现一个 ...

  8. 三.RabbitMQ之异步消息队列(Work Queue)

    上一篇文章简要介绍了RabbitMQ的基本知识点,并且写了一个简单的发送和接收消息的demo.这一篇文章继续介绍关于Work Queue(工作队列)方面的知识点,用于实现多个工作进程的分发式任务. 一 ...

  9. Angular相关命令

    1 创建相关 1.1 创建项目 ng new 项目名  ->  创建新项目 ng new 项目名 --skip-install  -> 不进行模块安装  ng new 项目名 -si ng ...

  10. .Net Core在X86上实现Interlocked.Increment(ref long)的方式

    因为在X86上long会被分割为两个int进行操作, 那么Interlocked.Increment的实现成为了一个问题. 在一番搜索后未发现有现成的文章解释这个问题,于是我就动手分析了. 这篇是笔记 ...