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

[经验分享] Python的一些高级特性

[复制链接]

尚未签到

发表于 2015-12-2 10:42:06 | 显示全部楼层 |阅读模式
  内容基本上来自于廖雪峰老师的blog相当于自己手打了一遍,加强加强理解吧。
  http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000
Python的一些高级特性
Slot
  python是动态语言,所谓动态,就是可以先创建类的实例,之后再动态绑定属性或方法,比如下边这个例子:
  class Student(object)
      pass
  s=Student()
  s.name="asd"
  注意这里的pass就是相当于空语句,表示什么都不做。
  还可以进行方法的动态绑定,比如定义下面的方法,有点像java中反射的感觉。
  def set_age(self,age)
      self.age=age
  from types import MethodType
  s.set_age=MethodType(set_age,s,Student)
  其中三个形参的含义:
  将已经定义好的 set_age方法,绑定在Student类的实例s上。
  绑定的时候,仅仅是将set_age方法与实例s进行了绑定,这里的绑定,只能是与固定实例进行,要是通过s2=Student() s2.set_age()来进行方法调用,就是不起作用的,因为方法仅仅与s1实例进行了绑定。
  如果希望使得所有的类都适用,需要给class类绑定类方法:
  def set_score(self,score)
      self.score=score
  Student.set_score=MethodType(set_score,None,Student)
  这里的None表示这个类还没有实例
  注意前面的不同,这里再具体进行绑定的时候,前面直接写成了,类名.set_score的形式。
  实际情况中,有些时候,并不希望对实例的任意绑定都能够进行,这样随随便便就进行绑定想来也总是不太安全的行为。
  可以通过下面的方法来解决:在定义class的时候,通过添加__slot__变量,来限制该class类所能够添加的属性。
  class Student(object)
      __slot__=('name','age')
  注意通过__slot__定义仅对当前的类起作用,对继承的子类是不起作用的。
  除非在子类中也加上__slot__ ,这样就相当于子类的__slot__范围加上父类的__slot__范围。
  这样的话,能动态绑定的属性,就只有name和age两个。
  如果绑定一个超出__slot__中所限制的范围的属性进去,比如:
  s=Student()
  s.score=90
  这样就会报错。
函数式编程以及高阶函数
  所谓高阶函数,就是函数本身也能作为参数传入,很多语言中都有高阶函数的相关机制。
  能接受一个函数作为传递参数的函数,就称为高阶函数,所谓的函数式编程,就是指在程序中使用这种更高抽象程度的编程范式。
  比如MapReduce中的map函数
  map(f,[1,2,3,4,5])
  这个就是说把f 函数作用于[1,2,3,4,5]中的每个元素,当然也可以通过别的方式来执行类似的操作,比如把list循环一下,每个元素都作为参数传递给f 最后输出的结果,
  之后再放在一个新的list当中,但是这样并不是太简洁。
  map作为一个高阶函数,事实上是把运算规则抽象化了,想想,有点想泛函分析的感觉,就是某种更高程度的抽象,像是直接提炼了算子出来的那种。估计自己以后不太有机会学数学上更高程度的课程了,想想当初老师上课说,如果工科方面再往高学,泛函分析是必须要学的,想想有点可惜,题外话。
  运算规则抽象之后,不但可以对简单的f(x)=x^2计算,还可以按照算子的计算规则,对序列或者是矩阵,进行类似的运算,确实方便好多。
  reduce也是一个高阶函数,对于reduce而言,reduce可以把一个函数作用在一个序列[x1, x2, x3...]上,这个函数必须接收两个参数,reduce把当前这一步的结果继续和序列的下一个元素做累积计算,其效果就是:reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
  比方说一个序列求和的reduce的实现:
  def add(x,y)
      return x+y
  reduce(add,[1,3,5,7,9])
  这样,返回结果是25。
  感觉高阶函数的主要好处还是体现在数学性比较强的运算上,比如结合mapreduce把str转化为int:
  def fn(x,y)
      return x*10+y
  def char2num(s)
      return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
  reduce(fn,map(char2num,'13579'))
  先用map函数把序列中的每个元素转化为实际的数字,返回的结果可能是一个数字的列表之后再用fn函数进行数字结果的reduce操作,不断向后进行迭代每次都是之前得到的结果乘以10再加上后面的一个数字,这样不断进行累计,最后可以把分散的数字序列拼成一个实际的数字。
  函数式编程在排序算法中的应用:
  这个算是比较典型的,将比较结果抽象出来:两个元素x y进行比较,如果返回-1 x<y 返回0, x==y ,反之 x>y。
  因此这个排序的函数也是一个高阶函数,因为在它的参数中,可以传入一个 函数,这个函数的作用是用来进行比较。
  这个其实有点像模板方法模式,高级函数中定义好更高层次的函数的执行顺序,之后在调用的时候,将具体的执行函数传入。
  当然,高阶函数除了接受函数作为传递的参数之外,还可以将函数作为值来返回。
  比如下面的代码,在一个函数的内部又定义了另外一个求和的函数,并且将这个求和的函数返回:
  def lazy_sum(*args):
      def sum():
      ax=0
          for n in args:
          ax=ax+n
          return ax
  return sum
  调用f=lazy_sum(1,2,3,4,5)的时候,返回的只是函数的一个句柄:
  只有再继续执行f()才能返回最后的结果:15。
  还有一个地方要注意的是:
  每次一个新的调用f1=lazy_sum(1,2,3) f2=lazy_sum(1,2,3) print f1==f2 结果就会返回false,f1()与f2()是两个不同的调用
匿名函数
  匿名函数往往通过 Lambda表达式的方式来引入:
  关键字lamda表示的是匿名函数,冒号前面的x表示的是函数的参数。
  如果定义一个lamda x:x*x实际上表示的就是:
  def f(x)
      return x*x
  匿名函数有一个限制,就是不用写return 这个表达式的返回值,就是最后的返回值。
  用匿名函数的好处是,因为函数没有名字,因此不必担心命名冲突。
  此外,匿名函数也是一个函数的对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数。
  当然通过lamda表达式定义的匿名函数也可以作为返回值来进行返回:
  def build(x,y)
      return lambda: x*x + y*y
  注意这里lamda表达式本身就是写在函数里面的,因此就不用再在:的前面把x,y再当做函数参数进行声明了
装饰器
  本质上decorator就是一个返回高阶函数的函数。
  可以通过动态的方式给原来的函数添加新的功能,比如打印日志
  比如我们定义一个log装饰器 对func方法进行包装
  def log(func):
      #这里添加了新的功能之后又将原来的函数返回
      def wrapper(*args,**kw):
          print 'call %s():' % func.__name__
          return func(*args,**kw)
  return wrapper
  利用python的 @ 语法 把decorator置于函数的定义处 这里大概的意思就是把下面的函数作为参数 传入之前定义好的log函数中
  这里相当于执行了类似下面的函数:now=log(now)原本的now函数还是存在的 只是现在同名的now变量指向了一个新的函数
  再次调用now()的时候 返回的是wrapper函数 此时now.__name__就是wrapper而不是now(这里要特别注意)
  @log
  def now():
      print '2014-12-06'
  调用now()
  打印的结果如下:
  call now():
  2014-12-06
  如果在decorator本身需要参数 就需要写一个返回decorator的参数 而不是一个仅仅返回wrapper的参数
  就是在wrapper的外层多套了一层decorator 这里要连续返回两层
  def log(text):
      def decorator(func):
          def wrapper(*args,**kw):
          print '%s %s():' %(text,func.__name__)
          return func(*args,**kw)
      return wrapper
  return decorator
  使用的时候:
  @log('execute')
  def now():
      print '2013-12-25'
  这个大概表示的意思就是 now=log('execute')(now)
  首先调用log('execute') 返回的是最外层的decorator函数 对log可见的是这个返回的decorator函数
  之后再调用这个返回的decorator函数 就是调用decorator(now) 来执行对应的wrapper函数
  此时now.__name__就变成了wrapper
  注意不论是两层还是三层 最里边总是一个wrapper的函数
  一个完整的decorator的写法:
  import functools
  def log(func)
      @functools.wraps(func)
      def wrapper(*args,**kw)
          print 'call %s() ' %func.__name__
      return func(*args,**kw)
  return wrapper
  对于带参数的wrapper
  import functools
  def log(text):
      def decorator(func):
      @functools.wraps(func)
          def wrapper(*args, **kw):
          print '%s %s():' % (text, func.__name__)
          return func(*args, **kw)
      return wrapper
  return decorator
  关键是要注意在wrapper的前面加上@functools.wrap(func)
  ??这里还是有一些疑问的
偏函数
  这里的偏函数和数学上的偏函数概念有所不同
  偏函数这个理解起来其实也比较容易
  就是函数中的某些参数被设定了默认值
  比如int ('12345',base=10)
  要是第二个参数没有显式地传进来的话 就是默认使用base=10来进行操作

运维网声明 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-146244-1-1.html 上篇帖子: 【Python学习】指定两点地理位置经纬度的距离计算 下篇帖子: 开启vim的Python支持
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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