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

[经验分享] python新手笔记之python高级函数编程

[复制链接]

尚未签到

发表于 2017-4-25 12:50:12 | 显示全部楼层 |阅读模式
python是一种非常强强大的脚本语言,不仅在于编程简洁,而且借鉴了很多其他语言的精妙之处,开始学python的时候听说python是对于编程初学者而言最好的语言,我现在觉得这句话一点也不意外,python确实做到了精简与强大并存,话不多说,整理一下python的超级强大的高级函数

 

1,reduce——递归编程的利器

 问题入门:我们现在需要计算一下N的阶乘,能够想到的方法自然是递归,当然为了介绍reduce,我们肯定是不使用我们熟悉的递归,让我们来看一下reduce的定义:

 

reduce(function, sequence[, initial])

 

其中,function是传入的函数,其中注意参数只能是两个,sequence是一个序列,后面的initial参数是可选参数,表示最开始操作的数,如果不输入的话,表示开始的第一个参数是序列的第一个数

 

下面通过代码计算一下N的阶乘


def mul(x,y):
return x*y
l=range(20)
print reduce(mul,l)

 只需四行代码,就能计算阶乘了,至于实现的原理,其实也不复杂,我们只需看一下官网的关于reduce的解释即可:


def reduce(function, iterable, initializer=None):
it = iter(iterable)
if initializer is None:
try:
initializer = next(it)
except StopIteration:
raise TypeError('reduce() of empty sequence with no initial value')
accum_value = initializer
for x in it:
accum_value = function(accum_value, x)
return accum_value
 看了官方文档的代码是不是豁然开朗,其实也很简单,说到底还是我们最原始的操作,但是不可否认,python对于常见函数的封装极大地降低了编程初学者的难度,也提高了编程的兴趣

 

2,lambda表达式——简化函数的利器

 

lambda表达式说穿了也就是一个简化的函数,主要用在一些比较简短的函数代替,如果函数比较复杂还是尽量使用def 定义一个函数,下面我们看一下Lambda的用法:


f=lambda x,y: x+y
print f(2,3)

 是不是很简单

 

3,函数的回调callback——比C++中的回调好用多了

大家应该知道,在VC++开发中,函数的回调非常麻烦,各种函数的指针搞来搞去,头都晕了,在python中不要太简单

以一个代码做简单介绍


def send_weixin(addr,message):
print u"发微信("+message+u")给"+addr
def send_email(addr,message):
print u"发邮件("+message+u")给"+addr
def send_qq(addr,message):
print u"发QQ("+message+u")给"+addr
def send_duanxin(addr,message):
print u"发短信("+message+u")给"+addr
send_method={
'QQ':send_qq,
'WeiXin':send_weixin,
'DuanXin':send_duanxin,
'Email':send_email
}
clients={("QQ","73465937","cehngxiansheng"),
("WeiXin","ffaazf","xufuren"),
("DuanXin","12345678","wangxiao"),
("Email","123@hot.com","jack")}
def send_messages():
for info in clients:
send_method[info[0]](info[1],info[2])
if __name__ =="__main__":
send_messages()
 上面代码主要是将消息发送给不同联系方式的人,根据不同人物的联系方式选择不同的发送函数,我们可以看到其回调函数 send_method[info[0]](info[1],info[2]) 简单的就像是字符串拼接,一个词评价“给力”!

 

 4,函数的闭包——python高手编程法宝

 

python的函数闭包closure有点像是Java的内部类,这是python的高手编程经常使用的方法,在一些地方用到这种方法会起到意想不到的效果

通过一个例子感受一下


def getMax(x):
def getMax_f(value):
return True if value>x else False
return getMax_f
maxFun=getMax(5)
if(maxFun(7)):
print "True"
 上面代码定义了一个比较函数,maxFun()如果一个大于5则打印“True”,反之“False”,其实我们可以这样理解python的闭包,也就是执行一遍自身再返回自身,上面的例子中,先运行一遍getMax()并且使用参数5初始化getMax_f,然后再返回getMax_f

 

5,Decorator装饰者模式,经典设计模——python中的“AOP”

在SPring中有个叫“AOP”编程的东西,大家应该不会陌生,面向切面编程的饿实质其实是动态代理的实现,只不过Spring实现的更加好,虽然装饰者模式和动态代理实现起来还是有区别,但是两者的整体实现思想其实差不多,在python中也会有这种实现方式,只不过是以一种更加简单的方式实现出来,不得不感叹Python设计者的牛逼之处

装饰者模式的概念很多讲设计模式的书上已经说了,这里就不再累述,着重看一下python的实现Decorator

 来看一下最简单的Decorator

 

 


def decorator(f):
print "decorator "+f.__name__+"is called"
return f
def fun1():
print "fun1 is called"
decorator(fun1)()

 看一下打印结果

 

 


decorator fun1is called
fun1 is called
 当然还有另一种通过注释方式写法:


def decorator(f):
print "decorator "+f.__name__+"is called"
return f
@decorator
def fun1():
print "fun1 is called"
fun1()
 两种执行的结果都一样

代码很容易看懂,其实这很类似函数的闭包,只不过返回的是自身的函数,这里需要说明的是如果使用@注释来调用的话,@这段代码会在程序加载的时候就执行,如下代码


def decorator(f):
print "decorator "+f.__name__+"is called"
return f
@decorator
def fun1():
print "fun1 is called"
##fun1()
 这段代码打印的结果如下


decorator fun1is called
 也就是说即使没有调用fun仍然会执行decorator里面的函数

举一个日常常用的使用装饰者的例子,通常在统计性能的时候我们会检测一下函数执行的时间,如果在每个函数中都加一段代码的话肯定会非常麻烦,这也不适合软件设计的基本思想,这样的话我们可以把计算时间的函数写在装饰器里面,如下

 


import time
def time_cost(f):
start=time.clock();
a=f()
end=time.clock()
print "time cost is",end-start
return a
@time_cost
def for_loop():
return [(x,y) for x in range(10) for y in range(10) if x*y>25 ]
li = for_loop
print len(li)

 这样就可以进行 时间计算了,注意这里面并没有将返回值设置为f而是设置为一个list,因此,装饰后的函数就不具备函数特性了,只是一个list

 

到这时候,装饰器还存在几个问题,第一个就是使用@注解的时候程序会在加载的时候就执行,但往往我们并不需要它执行,第二个问题是装饰器中并不能为传入的函数传递参数,要解决这几个问题,还得回到python中函数闭包函数,如下的代码中,我们使用闭包函可以解决如上的问题,代码如下:


import time
def time_cost(f):
def time_cost_f(length):
start=time.clock()
a=f(length)
end=time.clock()
print "time cost is",end-start
return a
return time_cost_f
@time_cost
def for_loop(length):
return [(x,y) for x in range(length) for y in range(length) if x*y>25 ]
for_loop(1000)
 这样就解决了@注释会提前执行的不足,当然也可以进行多参数传递,只需要修改那个函数中的参数即可

到这里,已经解决了装饰器的绝大部分功能,但是我们还有一个疑问,就是能不能给装饰器传一个参数,比如我们需要获取一个函数执行1000次的最少时间和平均时间,这就需要用到三层嵌套,代码如下

 

 


import time
def time_cost(times):
def time_cost_f(f):
def time_cost_f_f(length):
count_mini_time=1000000.0
avg_time=0
sum_time=0
for i in range(times):
start=time.clock()
a=f(length)
end=time.clock()
sum_time+=(end-start)
if (end-start)<count_mini_time:
count_mini_time=end-start
avg_time=float(sum_time)/times
print "mini_time= " +str(count_mini_time)+"  avg_time=  "+str(avg_time)
return a
return time_cost_f_f
return time_cost_f
@time_cost(100)
def for_loop(length):
return [(x,y) for x in range(length) for y in range(length) if x*y>25 ]
print len(for_loop(100))
 如上可以看出,其实三层嵌套也不过是在嵌套器外面加一个参数,并使用一个闭包,代码很好看,我们看一下结果:

 


mini_time= 0.00128539609795  avg_time=  0.00154667338015
9714
 

6,迭代器iterator,本来今天准备说一下send函数和next函数,但是今晚朋友生日喝了点酒,就不写了,迭代器可以参照之前的篇章,也是一个比较有用的方法

运维网声明 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-369157-1-1.html 上篇帖子: 【跟我学Python】第四章. Python多线程编程 下篇帖子: Python C API 使用心得
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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