在python中一切都可以视作为对象,包括函数。我们来看个例子:
def function_try():
    '''it is funciton try doc'''
   
print 'function_try'
if
__name__=="__main__":
    print function_try.__doc__
    print function_try.__name__
E:\python2.7.11\python.exe E:/py_prj/fluent_python/chapter5.py
it is funciton try doc
function_try
在这里__doc__输出了函数function_try在开头的帮助。__name__则是输出了具体的函数名
我们还可以将函数名赋值给变量。通过变量的形式来访问
def function_try():
    '''it is funciton try doc'''
   
print 'function_try_print'
if
__name__=="__main__":
    fun=function_try
    print fun.__doc__
    print fun.__name__
    fun()
E:\python2.7.11\python.exe E:/py_prj/fluent_python/chapter5.py
it is funciton try doc
function_try
function_try_print
 
函数也可以通过参数被传递给另外一个函数。
def function_try():
    '''it is funciton try doc'''
   
print 'function_try_print' def function_try1(fun):
    print fun.__doc__
    print fun.__name__
    fun() if __name__=="__main__":
    f=function_try
    function_try1(f)
 
下面来介绍下函数的高级用法。
假设有一字符列表,想通过各个字符的长度来进行排序。我们首先想到的是下面的方法。用sort的方法,并在key中指明排序的依据。在这里用到了lambda来得到每个元素的长度。
fruits=['strawberry','fig','apple','cherry','rasberry','banana']
fruits.sort(key=lambda x:len(x))
print fruits
E:\python2.7.11\python.exe E:/py_prj/fluent_python/chapter5.py
['fig', 'apple', 'cherry', 'banana', 'rasberry', 'strawberry']
还可以直接用sorted的方法。不同的是sorted是另外返回一个排序后的列表,原列表fruits并没有发生改变
fruits=['strawberry','fig','apple','cherry','rasberry','banana']
ret=sorted(fruits,key=len)
print 'after sorted %s' % ret
print 'before sorted %s' % fruits
E:\python2.7.11\python.exe E:/py_prj/fluent_python/chapter5.py
after sorted ['fig', 'apple', 'cherry', 'banana', 'rasberry', 'strawberry']
before sorted ['strawberry', 'fig', 'apple', 'cherry', 'rasberry', 'banana']
 
下面来介绍几个高阶函数:map,filter,reduce
首先来看下map的定义:

map(functioniterable...)

Apply function to every item of iterable and return a list of the results. If additional iterable arguments are passed,function must take that many arguments and is applied to the items from all iterables in parallel. If one iterable is shorter than another it is assumed to be extended withNoneitems. If function isNone, the identity function is assumed; if there are multiple arguments, map() returns a list consisting of tuples containing the corresponding items from all iterables (a kind of transpose operation). The iterable arguments may be a sequence or any iterable object; the result is always a list.

简单归纳就是对于可迭代对象iterable中的每一个元素应用function方法。并将结果做为list返回
来看下例子:
def add_num(n):
    return n+1 if __name__=="__main__":
    print map(add_num,range(1,6))
range(1,6)中的各个元素都被add_num调用然后生成一个列表。其实效果相当于[add_num(n) for n in range(1,6)].因此map可以看做是一个列表推导式
我们再来另外一个应用
def add_num(a,b,c):
    return a+b+c if __name__=="__main__":
    print map(add_num,range(1,6),range(7,12),range(11,16))
E:\python2.7.11\python.exe E:/py_prj/fluent_python/chapter5.py
[19, 22, 25, 28, 31]
这个写法的作用是将3个range中的元素按照顺序依次想加。这样写是不是比逐个遍历要方便很多。
再来看下filter。
s=[1,2,3,4,5]
print filter(lambda x:x>3,s)
E:\python2.7.11\python.exe E:/py_prj/fluent_python/chapter5.py
[4, 5]
Filter的作用在于根据第一个参数为true还是false来进行过滤。上面例子中将大于3的数值过滤出来。
 
下面介绍下reduce的作用。我们先来看下说明:
Apply a function of two arguments cumulatively to the items of a sequence,
from left to right, so as to reduce the sequence to a single value.
For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates
((((1+2)+3)+4)+5).  If initial is present, it is placed before the items
of the sequence in the calculation, and serves as a default when the
sequence is empty.
上面的说明很形象了,就是将参数累加的应用于函数中。就好比我们要对1到100进行求值。代码如下。效果等同于sum(range(100))
from operator import add
print reduce(add,range(100))
E:\python2.7.11\python.exe E:/py_prj/fluent_python/chapter5.py
4950
对于reduce请注意这句话:Apply a function of two arguments cumulatively to the items of a sequence,意思是传入的函数必须接受2个参数。意味着传输的计算源必须至少是有2个。
 
前面介绍到可以把函数当做对象。那么我们可以像调用函数那样调用类么。答案是肯定的。只需要我们重写类中的__call__就可以了
class function_try:
    def __init__(self,value):
        self.data=value
    def __call__(self, *args, **kwargs):
        print 'function try was called'
        for
a in args:
            print a if __name__=="__main__":
    f=function_try(3)
    print f(3,2)
E:\python2.7.11\python.exe E:/py_prj/fluent_python/chapter5.py
function try was called
3
2
当我们用print f(3,2).起作用的其实是__call__方法。
除了__doc__, __name__这些函数还有很多属性。可以用dir的方法进行查看
def add_num(a,b,c):
    return a+b+c
print dir(add_num)
E:\python2.7.11\python.exe E:/py_prj/fluent_python/chapter5.py
['__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__doc__', '__format__', '__get__', '__getattribute__', '__globals__', '__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name']
可以看到上面这么多的方法。类中也有很多的属性,哪些是函数特有的呢。可以写一个空类和空的函数来进行对比
class c:
    pass def func():
    pass
if
__name__=="__main__":
    print sorted(set(dir(func))-set(dir(c)))
 
函数参数的获取:首先来看下面的代码
 
def func_argument(text,length=10):
    if len(text) > length:
        ret='override'
    else
:
        ret=text[0:length]
    return ret
if __name__=="__main__":
    print func_argument.__defaults__
    print func_argument.__code__
    print func_argument.__code__.co_varnames
    print func_argument.__code__.co_argcount
运行结果:
E:\python2.7.11\python.exe E:/py_prj/fluent_python/chapter5.py
(10,)
<code object func_argument at 01875188, file "E:/py_prj/fluent_python/chapter5.py", line 36>
('text', 'length', 'ret')
2
 
__defaults__输出的是参数的默认值,这里length被初始化为10
__code__.co_varnames输出的是具体的参数名称。从结果可以看到输出有text,length,ret。不光是有传入的参数,还有内部定义的参数
__code__.co_argcount 代表的是函数传入参数的个数。通过__code__.co_argcount就可以知道在__code__.co_varnames哪些是函数传入的参数,哪些是函数内部定义的参数。
 
在前面曾经讲到过sorted的方法以及lambda的用法。这里再介绍一个高级点的用法:有一个列表,里面存储了各个城市的信息。我们想根据国家代码(第二个字段)的顺序打印各个城市的信息。大家第一反应肯定是用sorted,然后key值用lambda来表示:
metro_data=[('tokyo','jp','36.933',(35.689722,139.691667)),('Delhi NCR','IN',21.935,(28.613889,77.208889)),('Mexico city','MX',20.142,(19.43333,-99.13333))]
x=sorted(metro_data,key=lambda x:x[1])
其实我们可以用一个更简洁的方法:itemgetter
metro_data=[('tokyo','jp','36.933',(35.689722,139.691667)),('Delhi NCR','IN',21.935,(28.613889,77.208889)),('Mexico city','MX',20.142,(19.43333,-99.13333))]
for city in sorted(metro_data,key=itemgetter(1)):
    print city
通过代码比较其实可以发现itemgetter其实就和lambda x:x[1]的作用是一样的。
 
最后介绍一个可以冻结参数的功能。Functions.partial. 在某些场景下,我们期望可以冻结一个参数,并将这个参数作用于其他参数。代码如下:
from functools import partial
from operator import mul
 
triple=partial(mul,3)  #将第一个参数固定为3
print triple(7)    #=7*3
print list(map(triple,range(1,10))) #1,10分别和3相乘
 
E:\python2.7.11\python.exe E:/py_prj/fluent_python/chapter5.py
21
[3, 6, 9, 12, 15, 18, 21, 24, 27]

流畅的python学习笔记:第五章的更多相关文章

  1. [Python学习笔记][第五章Python函数设计与使用]

    2016/1/29学习内容 第四章 Python函数设计与使用 之前的几页忘记保存了 很伤心 变量作用域 -一个变量已在函数外定义,如果在函数内需要修改这个变量的值,并将这个赋值结果反映到函数之外,可 ...

  2. 流畅的python学习笔记:第二章

    第二章开始介绍了列表这种数据结构,这个在python是经常用到的结构 列表的推导,将一个字符串编程一个列表,有下面的2种方法.其中第二种方法更简洁.可读性也比第一种要好 str='abc' strin ...

  3. 流畅的python学习笔记:第一章

    这一章中作者简要的介绍了python数据模型,主要是python的一些特殊方法.比如__len__, __getitem__. 并用一个纸牌的程序来讲解了这些方法 首先介绍下Tuple和nametup ...

  4. 流畅的python学习笔记第七章:装饰器

    装饰器就如名字一样,对某样事物进行装饰过后然后返回一个新的事物.就好比一个毛坯房,经过装修后,变成了精装房,但是房子还是同样的房子,但是模样变了. 我们首先来看一个函数.加入我要求出函数的运行时间.一 ...

  5. Python学习笔记 -- 第五章

    模块 使用模块可以提高了代码的可维护性.其次,编写代码不必从零开始.当一个模块编写完毕,就可以被其他地方引用.我们在编写程序的时候,也经常引用其他模块,包括Python内置的模块和来自第三方的模块: ...

  6. 流畅的python学习笔记:第九章:符合python风格的对象

    首先来看下对象的表现形式: class People():     def __init__(self,name,age):         self.name=name         self.a ...

  7. python学习心得第五章

    python学习心得第五章 1.冒泡排序: 冒泡是一种基础的算法,通过这算法可以将一堆值进行有效的排列,可以是从大到小,可以从小到大,条件是任意给出的. 冒泡的原理: 将需要比较的数(n个)有序的两个 ...

  8. python学习笔记(五岁以下儿童)深深浅浅的副本复印件,文件和文件夹

    python学习笔记(五岁以下儿童) 深拷贝-浅拷贝 浅拷贝就是对引用的拷贝(仅仅拷贝父对象) 深拷贝就是对对象的资源拷贝 普通的复制,仅仅是添加了一个指向同一个地址空间的"标签" ...

  9. Python学习笔记(五)

    Python学习笔记(五): 文件操作 另一种文件打开方式-with 作业-三级菜单高大上版 1. 知识点 能调用方法的一定是对象 涉及文件的三个过程:打开-操作-关闭 python3中一个汉字就是一 ...

  10. Programming Entity Framework-dbContext 学习笔记第五章

    ### Programming Entity Framework-dbContext 学习笔记 第五章 将图表添加到Context中的方式及容易出现的错误 方法 结果 警告 Add Root 图标中的 ...

随机推荐

  1. java集合系列—ArrayList

    ArrayList是工作以来使用频率最高的集合类.以前上课老师说不知道用什么集合类就用ArrayList,好吧,后面就这样了. public class ArrayList<E> exte ...

  2. 通过批处理 安装 mongodb和设置身份验证

    1.首先需要 mongodb.msi安装包 2.mongodb的配置文件mongod.cfg 内容如下: systemLog: destination: file path: "D:/mon ...

  3. java-cef嵌入基于Chrome内核浏览器,做页面爬虫(可以尽在ajax异步请求数据)

    1 CentOS 7.0 上安装和配置 VNC 服务器 2.1 2.1.1 首先,我们需要一个可用的桌面环境(X-Window),如果没有的话要先安装一个. 注意:以下命令必须以 root 权限运行. ...

  4. 使用Maven管理Oracle驱动包

    由于Oracle授权问题,Maven3不提供Oracle JDBC driver,为了在Maven项目中应用Oracle JDBC driver,必须手动添加到本地仓库. 手动添加到本地仓库需要本地有 ...

  5. struts和struts2的区别

    1.Structs2简介和Structs2开发环境搭建 一.Structs2简介: 1.什么是Struct2? 著名的SSH三大框架分别为:表现层(Structs).业务逻辑层(Spring),持久化 ...

  6. 华为ensp模拟某公司网络架构及配置详解

    1.先晒下架构图,二层设备省略..... 2.下面开始具体配置详解 2.1.从路由器开始配置,先用远程工具远程AR1220F-S路由,secureCRT ,putty,xshell任选其中一个均可,功 ...

  7. MySQL数据库使用mysqldump导出数据详解

    mysqldump是mysql用于转存储数据库的实用程序.它主要产生一个SQL脚本,其中包含从头重新创建数据库所必需的命令CREATE TABLE INSERT等.接下来通过本文给大家介绍MySQL数 ...

  8. 无声的吐槽csdn

    上次朋友聚会,说csdn挺好的,我琢磨着,那好我也去注册一个.经过n次的注册(用户名那边老是验证不过,不给中文开头,然后随便填了一个),终于搞定了! 我想,不错啊,做了这么多限制,挺安全的感觉.然后我 ...

  9. 《HelloGitHub》第 14 期

    公告 欢迎通过在 GitHub 上新建 issues 方式推荐项目,我真心希望读者可以在 HelloGItHub,找到真正的编程乐趣! <HelloGitHub>第 14 期 兴趣是最好的 ...

  10. [asp.net mvc 奇淫巧技] 03 - 枚举特性扩展解决枚举命名问题和支持HtmlHelper

    一.需求 我们在开发中经常会遇到一些枚举,而且这些枚举类型可能会在表单中的下拉中,或者单选按钮中会用到等. 这样用是没问题的,但是用过的人都知道一个问题,就是枚举的命名问题,当然有很多人枚举直接中文命 ...