zoukankan      html  css  js  c++  java
  • 写出pythonic的python代码

    http://www.cnblogs.com/dadadechengzi/p/6226071.html

    1,列表推导(没当要对序列中的内容进行循环处理时,就应该尝试使用列表推倒)

      在python中编写如下的代码是让人痛苦和不高效已经简洁美观的。

    复制代码
    numbers =  range(10)
    evens = []
    for i in numbers:
        if i % 2 == 0:
            evens.append(i)
    
    print evens
    复制代码

      毫无疑问,在python中它确实会使得程序的执行速度变得慢了(它使解释程序在每次循环中都要确定序系中哪一部分被修改)

      列表推倒是这种场景下的争取选择,它使用编排好的特性对前述语法中的一部分进行了自动化处理:

      events = [i for i in range(10) if i % 2 == 0]

      这种编写的方法除了高效之外,也更加简短,涉及的元素也更少。在更大的程序中,这意味着引入的缺陷更少,代码更加容易阅读和理解。

    2,使用枚举(enumerate)

      比如下面的代码就可以换成使用枚举:

    复制代码
    i = 0
    seq = ['one','two','three']
    for element in seq:
        seq[i] = '%d:%s' % (i,seq[i])
        i += 1
    
    print seq
    复制代码
    seq = ['one','two','three']
    for index,element in enumrate(seq)
        seq[i] = '%d:%s' % (index,element)
    
    print seq

      也可以结合一个列表推倒将其重构如下:

    复制代码
    def _treatment(pos,element):
        return '%d:%s' % (pos,element)
    
    seq = ['one','two','three']
    seq = [_treatment(index,ele) for index,ele in enumrate(seq)]
    
    print seq
    复制代码

    3,迭代器

      迭代器只不过是一个实现迭代协议的容器对象,它基于两个方法:

    1. next 返回容器的下一个项目;
    2. __iter__ 返回迭代器本身

      创建定制的迭代器:

    复制代码
    class My_Iteration(object):
        def __init__(self,step):
            self.step = step
        
        def next(self):
            if self.step == 0:
                raise StopIteration
            self.step -= 1
    
        def __iter__(self):
            return self
    
    for i in My_Iteration(5):
        print i
    复制代码

      迭代器本身提供了一个底层的概念,它们为生成器这一更有趣的特性提供了基础。

    4,生成器(当需要一个将返回一个序列或者在循环中执行的函数时就应该考虑使用生成器)

      生成器提供了一个出色的方法,使得需要返回一系列元素的函数所需的代码更加的简单、高效。基于yield指令,可以暂停一个函数并返回中间结果。该函数将保存执行环境并在必要的时候恢复。

      生成器对降低程序复杂性也有帮助,并且能够提升基于多个序列的数据转换算法的性能。把每个序列当做一个迭代器,然后将他们合并到一个高级别的函数中,这是一种避免函数变得更加庞大,丑陋,不可理解的好办法,而且,这可以给整个处理链提供实时的反馈。

      在下面的例子中,每个函数用来在序列上定义一个转换,然后他们被链接起来应用,每次调用将处理一个元素并返回其结果:

    复制代码
    def power(values):
        for value in values:
            print 'power %s' % value
            yield value
    
    def adder(values):
        for value in values:
            print 'adder %s' % value
            if value % 2 == 0:
                yield value + 3
            else:
                yield value + 2
    
    elements = [1,2,3,4,5,7,8]
    res = adder(power(elements))
    
    #res 就是一个生成器了
    复制代码

    5,装饰器(decorator)

      装饰器使得函数和方法封装(接受一个函数并返回增强版本的一个函数)更加容易阅读和理解。其实总体说来,装饰器也就是一个函数,一个用来包装函数的函数,返回一个修改之后的函数对象,将其重新赋值原来的标示符,并永久丧失对原始函数对象的访问。

      语法:

    • 无参数装饰器
    复制代码
    def deco(fun):    
        print fun    
        return fun
    @deco
    def foo():
        pass
    foo()
    复制代码

      第一个函数deco是装饰函数,它的参数就是被装饰的函数对象,我们可以在deco函数内对传入的函数对象做一番“装饰”,然后返回这个对象(一定要返回 ,不然外面调用foo的地方将会无函数可用。实际上此时foo=deco(foo))

      下面有个例子检查函数有没有说明文档:

    复制代码
    def deco_functionNeedDoc(func):
        if func.__doc__ == None:
            print func,"has no __doc__,it's a bad habit."
        else:
            print func,":",func.__doc__,"."
        return func
    
    @deco_functionNeedDoc
    def f():
        print 'f() has no doc'
    #f = deco_functionNeedDoc(f)
    
    @deco_functionNeedDoc
    def g():
        'I have a __doc__'
        print 'g() has doc'
    #g = deco_functionNeedDoc(g)
    
    f()
    g()
    复制代码
    • 有参数装饰器
    复制代码
    def deco_maker(arg):
        '通常对arg会有一定的要求'
        """由于有参数的decorator函数在调用时只会使用应用时的参数而不接收被装饰的函数做为参数,所以必须在其内部再创建一个函数"""
        
        def newDemo(func):#定义一个新的decorator函数
            print func, arg
            return newDemo
        return newDemo
    
    @deco_maker(deco_args)
    def foo():pass
    
    foo()
    复制代码

      第一个函数deco_maker是装饰函数,它的参数是用来加强“加强装饰”的。由于此函数并非被装饰的函数对象,所以在内部必须至少创建一个接受被装饰函数的函数,然后返回这个对象(实际上此时foo=decomaker(arg)(foo))

      总结:装饰器可以让函数轻装上阵,更重要的是将函数的约束放置于接口处,使意图更加明了,同时又不增加调用者的负担。

      再看一个例子:

    复制代码
    import time,logging
    logger = logging.getLogger()
    logger.setLevel(logging.DEBUG)
    is_debug = True
    
    def count_time(is_debug):
        def handle_func(func):
            def handle_args(*args,**kwargs):
                if is_debug:
                    begin = time.time()
                    func(*args,**kwargs)
                    logging.debug("[" + func.__name__ + "] -> " + str(time.time() - begin))
                else:
                    func(*args,**kwargs)
            return handle_args
        return handle_func
    
    def pr():
        for i in range(1,1000000):
            i = i * 2
        print 'hello world'
    
    def test():
        pr()
    
    @count_time(is_debug)
    def test2():
        pr()
    
    @count_time(False)
    def test3():
        pr()
    
    if __name__ == '__main__':
    #    f()
    #    g()
        test()
        test2()
        test3()
    复制代码

      参考:http://blog.csdn.net/wklken/article/details/8118942

    6,with语句

      对于确保即使发生错误时也能运行一些清理代码而言,try...finally语句是很有用的,对此有许多的场景,如:

    • 关闭一个文件
    • 释放一个锁
    • 创建一个临时的代码补丁
    • 在特殊环境中运行受保护的代码

      with语句覆盖了这些使用场景,为在一个代码前后调用一些代码提供了一种简单的方法。例如,文本的读取通常如下实现:

    复制代码
    hosts = open('/etc/issus')
    
    try:
        for line in hosts:
            if line.startswith('#')
                contine
            print line
    finally:
        hosts.close()
    复制代码

      通过使用with语句,以上代码可以重构如下:

    复制代码
    from __future__ import with_statement
    
    with open('/etc/issue') as hosts:
        for line in hosts:
            if line.startswith('#')
                continue
            print line
    复制代码

    7,

  • 相关阅读:
    【Python3】操作文件,目录和路径
    Python中的文件和目录操作实现
    【Python 2 到 3 系列】 此整型非彼整型
    【Python 2 到 3 系列】 print 是函数
    css网页中设置背景图片的方法详解
    (转)开源项目miaosha(下)
    (转)开源项目miaosha(上)
    (转)开源项目t-io
    (转)WebSocket学习
    缓存问题参考
  • 原文地址:https://www.cnblogs.com/dadadechengzi/p/7063687.html
Copyright © 2011-2022 走看看