Python2.4新特性(部分)

时间:2022-08-24 04:00:00

1.PEP218:内建set对象
      set对象有点类似于序列对象(str,list,tuple)也是其他对象的容器,但set对象内的元素是不重复的(这和java.util.Set)
      语义一致,并且set提供了方便的集合运算功能
        >>> a = set('abracadabra')              # 从字符串创建set对象
  >>> 'z' in a                            # 支持 in 操作符
  False
  >>> a                                   # 元素唯一,消除了重复元素
  set(['a', 'r', 'b', 'c', 'd'])
  >>> ''.join(a)                          # 将set中每个元素组成字符串,和list用法一样
  'arbcd'

  >>> b = set('alacazam')                 # 另一个set
  >>> a - b                               # 在a中而不在b中的新set
  set(['r', 'd', 'b'])
  >>> a | b                               # 在a中或者在b中
  set(['a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'])
  >>> a & b                               # 同时在a和b中
  set(['a', 'c'])
  >>> a ^ b                               # 不同时在a和b中
  set(['r', 'd', 'b', 'm', 'z', 'l'])

  >>> a.add('z')                          # 增加新的单个元素
  >>> a.update('wxy')                     # 增加按照序列元素拆分的多个元素
  >>> a
  set(['a', 'c', 'b', 'd', 'r', 'w', 'y', 'x', 'z'])
  >>> a.remove('x')                       # 删除指定的元素
  >>> a
  set(['a', 'c', 'b', 'd', 'r', 'w', 'y', 'z'])

   frozenset是set的不可变版本,这就意味这一旦frozenset构造后就不能往其中增,删,改任何元素,所以可以作为dict的key
   标准库中还有一个sets模块,sets模块中有Set和ImmutableSet类,现在可以直接从set和fronzenset继承.

 2.PEP237:统一整数和长整数
   例如:2 << 32 在python2.3中有警告信息,32位操作系统得出的结果是0,而在python2.4中,结果是8589934592L

 3.PEP 289:发生器表达式(Generator Expressions)
   python2.2的iterator特性和itertools模块使程序可以轻松的循环数据量大的集合而不需要在内存中保存整个集合对象.
   列表理解(list comprehension)并不适合这种情况,因为它创建了一个包含所有元素的python list对象,这在数据量大
   的情况下会有问题.比如 get_all_links()中存在大量的数据:
   links = [link for link in get_all_links() if not link.followed]
   for link in links:
       ...
   使用下面的代替
   for link in get_all_links():
       if link.followed:
           continue
       ...
   第一种形式(list comprehension)写法简练易读,但当get_all_links()中存在大量的数据的时候你应该使用第二种形式以
   避免将所有list元素放入内存,实际上for in 循环是内部是使用iter对象遍历的,iter对象有一个next方法,用于获取下一个
   元素,并通过产生StopIteration异常告知循环结束

   发生器表达式和list comprehension差不多但缺不需要在内存中建立整个list对象.代替的是:发生器表达式通过产生
   generator对象遍历元素.
   links = (link for link in get_all_links() if not link.followed)
   for link in links:
          ...
   发生器表达式使用写在()中间,并且和列表理解有一些细微的区别,最显著的是:循环变量(例如上面的link)不能在发生器表达式
   外部访问而列表理解会保存最后一次循环的值,在以后的python版本中这一方面会统一这两者的区别

 4.PEP 292: 简单String替代(Simpler String Substitutions)
   这种特性和velocity,freemarker的作用相似,即模板的运用
   最常用的替代如:
   >>> '%(page)i: %(title)s' % {'page':2, 'title': 'The Best of Times'}
   '2: The Best of Times'
      上面这种方式很容易在()后忘记使用i或者s,并在运行的时刻抛出异常信息.
      PEP292在string模块中添加了Template类,并使用"$"符号指示需要替换的内容,Template类是Unicode的子类,所以输出的
      结果是一个unicode字符串
      >>> import string
   >>> t = string.Template('$page: $title')
   >>> t.substitute({'page':2, 'title': 'The Best of Times'})
   u'2: The Best of Times'
   当key没提供的时候,t.substitute会抛出KeyError异常,如果你不需要这种行为,可以使用下面的方式:
   >>> t = string.Template('$page: $title')
   >>> t.safe_substitute({'page':3})
   u'3: $title'

    5.PEP318:方法装饰器 (Decorators for Functions and Methods )
      python2.2以后加入了staticmethod和classmethod,但没有提供一个方便的语法支持,比如:
      class A:
          def meth(cls):
              ...
          meth = classmethod(cls)
      这样meth就成为一个类方法(将类对象作为方法的第一个参数).
      这种写法的缺点是方法声明变长了并且容易忘记meth = classmethod(cls)调用

      python2.4提供了一种新的语法使这种方法定义有更好的可读性,这种新特性称为"function decorators",采用写的语法后:
      class A:
          @classmethod
          def meth(cls):
              ...
      @classmethod就是meth = classmethod(meth)的快捷方式
   装饰器必须在方法定义前,并且不能在一行上.装饰器本身只不过是一个可调用对象,并把方法本身作为参数传递,并返回方法本身或
   另一个可调用对象,下面的例子给函数加上新的属性
   def deco(func):
       func.attr = 'decorated'
       return func

   @deco
   def f(): pass

   >>> f
   <function f at 0x402ef0d4>
   >>> f.attr
   'decorated'

      下面是一个更现实的例子,用于检查传递的参数是否是int
      def require_int (func):
      def wrapper (arg):
          assert isinstance(arg, int),"the argument must be integer!"
          return func(arg)
      return wrapper

   @require_int
   def p1 (arg):
          print arg

   下面的例子使用类装饰一个方法
   class A:
       def __init__(self,func):
           self.func = func

       def __call__(self,*args):
           print "in A.__call__"
           return self.func(*args)
   @A
   def add(a,b):
       return a + b

   6.PEP 322: 反向遍历(Reverse Iteration)
  一个新的内建方法reversed(sequence)(reversed实际上是一个类),用于反向遍历sequence
  >>> for i in reversed(xrange(1,4)):
  ...     print i
  ...
  3
  2
  1
        reversed()仅仅接收序列参数而不是任意对象,如果您需要反向iter对象,需要显示的转换成list
        >>> input = open('/etc/passwd', 'r')
  >>> for line in reversed(list(input)):
  ...   print line
  ...
  root:*:0:0:System Administrator:/var/root:/bin/tcsh

   7.8省略...

   9.PEP 328: 多行导入(Multi-line Imports )
        在以前的python版本中,当导入语句很长的时候,方法如下:
       from SimpleXMLRPCServer import SimpleXMLRPCServer,/
            SimpleXMLRPCRequestHandler,/
            CGIXMLRPCRequestHandler,/
            resolve_dotted_attribute

    可以看到,加入了很多续行符(/),而在python2.4中把这些名字用括号包围就可以了
    from SimpleXMLRPCServer import (SimpleXMLRPCServer,
                                SimpleXMLRPCRequestHandler,
                                CGIXMLRPCRequestHandler,
                                resolve_dotted_attribute)

      10.省略...

      11.其他变化
         a.dict.update方法现在可以接收和dict构造器一样的参数,这包括任何dict,任何key/value对和关键字参数
         b.string的ljust,rjust,center方法可以接收一个可选参数用于指示用什么填充(老版本是空格)
         c.string的rsplit方法可以从右边分割字符串'www.python.org'.rsplit('.', 1) => ['www.python', 'org']
         d.list.sort方法加了三个关键字参数,cmp,key,reverse
           L = ['A','b','c','D']
          
           L.sort() -> ['A','D','b','c']
          
           cmp参数对应用于接收两个参数并比较的方法,返回-1,0,1.
           如L.sort(cmp=lambda x,y:cmp(x.lower(),y.lower())) -> ['A','b','c','D']
           这种情况下,将会取列表中的某两个元素,并调用cmp的方法对象,通过返回值排序
          
           key参数对应用于接收一个参数并返回需要比较的key
           如L.sort(key=lambda x:x.lower()) -> ['A','b','c','D']
           这种情况下,将列表中每个元素应用key对应的方法对象,并返回真实需要排序的key
          
           当然可以使用unbound-method来替换上面的例子,可以简单的写成
           L.sort(key=str.lower),结果是一样的
          
           reverse参数是一个bool实例(True|False),True表示按照反向排序
           L.sort(reverse=True) -> ['c','b','D','A']
           在以前的版本中需要写L.sort(),L.reverse()
         e.新增内置方法sorted(iterator),其工作方式和list.sort很相似,不过sorted内置方法可以用于表达式中,并
           返回新的排过顺的copy,而不是在原地(in-place)修改对象
          
        sorted(iterable, cmp=None, key=None, reverse=False) --> new sorted list
       
        >>> L = [9,7,8,3,2,4,1,6,5]
        >>> [10+i for i in sorted(L)]
        >>> [11, 12, 13, 14, 15, 16, 17, 18, 19]