流畅的python学习笔记:第五章
在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(function, iterable, ...)
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学习笔记:第五章的更多相关文章
- [Python学习笔记][第五章Python函数设计与使用]
2016/1/29学习内容 第四章 Python函数设计与使用 之前的几页忘记保存了 很伤心 变量作用域 -一个变量已在函数外定义,如果在函数内需要修改这个变量的值,并将这个赋值结果反映到函数之外,可 ...
- 流畅的python学习笔记:第二章
第二章开始介绍了列表这种数据结构,这个在python是经常用到的结构 列表的推导,将一个字符串编程一个列表,有下面的2种方法.其中第二种方法更简洁.可读性也比第一种要好 str='abc' strin ...
- 流畅的python学习笔记:第一章
这一章中作者简要的介绍了python数据模型,主要是python的一些特殊方法.比如__len__, __getitem__. 并用一个纸牌的程序来讲解了这些方法 首先介绍下Tuple和nametup ...
- 流畅的python学习笔记第七章:装饰器
装饰器就如名字一样,对某样事物进行装饰过后然后返回一个新的事物.就好比一个毛坯房,经过装修后,变成了精装房,但是房子还是同样的房子,但是模样变了. 我们首先来看一个函数.加入我要求出函数的运行时间.一 ...
- Python学习笔记 -- 第五章
模块 使用模块可以提高了代码的可维护性.其次,编写代码不必从零开始.当一个模块编写完毕,就可以被其他地方引用.我们在编写程序的时候,也经常引用其他模块,包括Python内置的模块和来自第三方的模块: ...
- 流畅的python学习笔记:第九章:符合python风格的对象
首先来看下对象的表现形式: class People(): def __init__(self,name,age): self.name=name self.a ...
- python学习心得第五章
python学习心得第五章 1.冒泡排序: 冒泡是一种基础的算法,通过这算法可以将一堆值进行有效的排列,可以是从大到小,可以从小到大,条件是任意给出的. 冒泡的原理: 将需要比较的数(n个)有序的两个 ...
- python学习笔记(五岁以下儿童)深深浅浅的副本复印件,文件和文件夹
python学习笔记(五岁以下儿童) 深拷贝-浅拷贝 浅拷贝就是对引用的拷贝(仅仅拷贝父对象) 深拷贝就是对对象的资源拷贝 普通的复制,仅仅是添加了一个指向同一个地址空间的"标签" ...
- Python学习笔记(五)
Python学习笔记(五): 文件操作 另一种文件打开方式-with 作业-三级菜单高大上版 1. 知识点 能调用方法的一定是对象 涉及文件的三个过程:打开-操作-关闭 python3中一个汉字就是一 ...
- Programming Entity Framework-dbContext 学习笔记第五章
### Programming Entity Framework-dbContext 学习笔记 第五章 将图表添加到Context中的方式及容易出现的错误 方法 结果 警告 Add Root 图标中的 ...
随机推荐
- 安卓模拟器tools修改
defaults write com.apple.finder AppleShowAllFiles -bool true 这步是显示隐藏文件夹, 然后打开finder,在应用程序上右键,选择在上层文件 ...
- zabbix常见问题整理 持续更新……
[toc] 1.zabbix仪表板错误 问题: zabbix server is not running: the information displayed may not be current 解 ...
- hdu1312 Red and Black 简单BFS
简单BFS模版题 不多说了..... 直接晒代码哦.... #include<cstdlib> #include<iostream> #include<cstdio> ...
- React入门---组件嵌套-5
组件嵌套 我们现在需要组件嵌套,所以要创建其他组件,目前有一个头部组件,在./components/header.js; 接下来在components文件中创建:底部组件footer.js 和主体组件 ...
- EntityFramework中出现DateTime2异常的完美解决办法
今天在使用entityframework往数据库插入数据的时候,突然出现了一个数据类型转换异常的问题: System.Data.SqlClient.SqlException: 从 datetime2 ...
- 从编译器角度理解C++中的引用和指针
欲分析指针和引用,则要分析变量名和地址之间的关系(不管你理解还是不理解,无论你是从老师那里听到的,还是网上看到的,应该都知道两句话:1. 指针就是地址,2.引用就是给变量起个别名) 所以我们就要来分析 ...
- GO的初始简书(一)简介安装
已经玩了很长一段时间的golang了,做个gopher,下面我将逐步展示各种go语言的开发,从入门开始哦,完全是凭着自己学习和实践的结果展示,如果有说的不对的,请指正. 简介 go语言是由Google ...
- Natas Wargame Level 9 Writeup(bash injection)
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAArAAAAClCAYAAACkwM63AAAABHNCSVQICAgIfAhkiAAAIABJREFUeF
- 数据结构与算法系列研究七——图、prim算法、dijkstra算法
图.prim算法.dijkstra算法 1. 图的定义 图(Graph)可以简单表示为G=<V, E>,其中V称为顶点(vertex)集合,E称为边(edge)集合.图论中的图(graph ...
- ASP.NET Gridview数据库绑定支持增删改,记得要完整实现
1.错误情况 /WebSite3"应用程序中的服务器错误. 指定的参数已超出有效值的范围. 参数名: index 说明: 执行当前 Web 请求期间,出现未经处理的异常.请检查堆栈跟踪信息, ...