zoukankan      html  css  js  c++  java
  • python

    前言

        内容摘自Python参考手册(第4版) 及 自己测试后得出。仅作为一个简单记录,方便使用查询之用。

    另 dir(func)及func.__doc__可以查看对象属性及说明文档。

    序列Sequence

       序列包括字符串、列表、元组。

    a = [5,6,3,2]
    b = [1,3]

    1、连接 s+r

    c = a + b # [5,6,3,2,1,3]

    2、解包 V1,V2..,Vn  = s

    v1,v2,v3,v4 = a #v1 = 5,v2 = 6 ,v3 = 3 ,v4 =2

    3、索引 s[i],切片 s[i:j],s[i:j:stride]

    v = a[0]       #  5
    c = a[0:2]     #  [5,6]
    d = a[0:2:2]   # [5]
    e = a[3:2:-1]  # [2]  stride负数则反过来取子序列

    4、从属关系 x in s , x not  in s 

    3 in a  #  True
    0 in a  #  False

    5、迭代  for x in s:

    for x in a:
        print x
    # 5 6 3 2

    6、其他 

    print all(a)      # True   全部为True返回True
    print any(a)      # True   任意为True返回True
    print len(a)      # 4       长度
    print min(a)      # 2       最小值
    print max(a)      # 6       最大值
    print sum(a)      # 16      和

    7、复制

    a = [ 1,2 ,[3,4]]
    b = list(a)  # 浅复制 地址拷贝,值类型拷贝
    b[0]      = 6    # a = [1,2,[3,4]]    b = [6,2,[3,4]]
    b[2][0] = 5    # a = [1,2,[5,4]]    b = [6,2,[5,4]]
    
    #  深拷贝
    import copy
    b = copy.deepcoy(a)
    b[2][0] =5         # a = [1,2,[3,4]]    b = [6,2,[5,4]]
    字符串格式化

       一、取模运算符(s%d) 生成格式化字符串,s是一个格式字符串,d是对象元组或映射对象(字典)。

    在 字符串内 %后修饰符意思:

    1)位于括号内的键名,映射对应字典内的对象。

    2)  ' - ' 字符 表示左对齐,默认右对齐。 ' + ' 表示包含数字符号(正负号)  。 ' 0 ' 表示一个零填充。

    3) 一个指定最小自动宽度的数字。(%10d ) 长度为10

    4) 一个小数点,按精度分割字段宽度。

    5) 一个数字,指定打印字符串的最大字符个数 ,浮点数中小数点之后的位数,或者整数最小位数。

    6) 星号(*),用于在任意宽度字段中替换数字。

    栗子: 

    a = 42
    b = 3.1415926
    c = "hello world"
    d ={'x':13,'y':b,'z':c}
    e = 123456789012345678901234567890
    r ="a is 10:%d  16:%x  8:%o" % (a,a,a)               #a is 10:42  16:2a  8:52
    r ="%10d %f  %E" % (a,b,b)                           #        42 3.141593  3.141593E+00
    r ="%(x)-10d %(y)0.3g" % d                           #13         3.14   #g,G表示指数小于-4使用%e或%E,否则使用%f
    stock ={
        'name': 'GooG',
        'shares':100,
        'price': 490.10
    }
    r = "%(shares)d of %(name)s at %(price)0.2f" % stock #100 of GooG at 490.10
    shares =111
    name ="currect_name"
    r = "%(shares)d of %(name)s" %vars()                 # 111 of currect_name #vars() 取当前变量名表示的值

       二、用字符串的 s.format(*args,*kwargs) 方法。

    1) {n} 占位符,n为数字,将被format()方法的位置参数n代替。

    2)  {name} 占位符,将被format()方法关键字参数name所代替。

    栗子:

    r = "{0} {1} {2} {age}".format('GOOG',100,490.10,age =47)      # GOOG 100 490.1 47
    r = "Use {{ and }} to output single curly braces".format()     # Use { and } to output single curly braces
    r = "{0[name]:8} {0[shares]:8d} {0[price]:0.3f}".format(stock) # GooG          100 490.100
    装饰器

       装饰器是一个函数,主要用途是包装另一个函数或类。

    栗子:

    1) 函数装饰器

    enable_tracing = True
    def trace(func):
        if enable_tracing:
            def callf(*args,**kwargs):
                print("Calling %s: %s, %s
    " % (func.__name__,args,kwargs))
                r = func(*args,**kwargs)
                print("%s returned %s
    " % (func.__name__,r))
                return r
            return callf
        else:
            return func
    
    @trace
    def square(x):
        return x*x
    print square(5)
    
    #>>>>>>>>>>>>>
    Calling square: (5,), {}
    
    square returned 25
    
    25

    上述trace就是装饰器,添加@trace相当于执行square = trace(square)。而为了保持被装饰函数的属性不被改变,装饰器需要做如下处理:

    def trace(func):
        if enable_tracing:
            def callf(*args,**kwargs):
                print("Calling %s: %s, %s
    " % (func.__name__,args,kwargs))
                r = func(*args,**kwargs)
                print("%s returned %s
    " % (func.__name__,r))
                return r
            callf.__doc__ = func.__doc__
            callf.__name__ = func.__name__
            callf.__dict__.update(func.__dict__)
            return callf
        else:
            return func

    2) 类装饰器:

    def register(cls):
        def cls__init(self): print 'register init!'    
        cls.__init__ =cls__init
        return cls
    @register
    class Foo(object):
        def __init__(self):
            print "Foo init!"
    
    Foo()  #register init!
    类对象

       类定义了一组属性,这些属性与一组叫做实例的对象相关且由其共享。类通常是由函数(方法)、变量(类变量)和计算出的属性(特性)组成的集合。

     1) 继承

    # 父类
    class classA(object):
        var = 0 
        def __init__(self):
            self.classname = classA.__name__ 
        def show(self):
            print self.var,self.classname
    # 子类
    class classB(classA):
        def __init__(self):
            classA.__init__(self)
            self.classname = classB.__name__ 
    f = classB()
    f.show()  #  0 classB

    实例方法默认第一个参数都是self,函数定义也要有self作为第一个参数。

    2) 静态方法

      相当于用类名作为命名空间的方式的普通函数。

    class Foo(object):
       @staticmethod
       def add(x,y):
           return x+y
    x = Foo.add(233,332)  # x = 565

    3) 类方法

      将类作为第一个参数的函数。

    class Foo(object):
       @classmethod
       def show_classname(cls):
           return cls.__name__
    f =  Foo()
    print  f.show_classname()    # 'Foo'
    print  Foo.show_classname()  # 'Foo'

    4) 特性 (property)

      实例或者类的属性方法,可以直接通过访问属性得到函数值。

    import math
    class Circle(object):
        __radius = 1.0
        @property
        def area(self):
            return math.pi*self.__radius**2
        @property
        def perimeter(self):
            return 2*math.pi*self.__radius
        @property
        def radius(self):
            return self.__radius
        @radius.setter
        def radius(self,var):
            self.__radius = var
        @radius.deleter
        def radius(self):
            self.__radius = 1.0
    f =  Circle()
    f.radius =4.0
    print f.area            #  50.2654824574
    print f.perimeter        # 25.1327412287
    del f.radius
    print f.area            # 3.14159265359
    print f.perimeter        # 6.28318530718  

    属性.setter和.deleter分别表示对属性设置和删除

    除了上述方法外,也可以用类的默认属性函数 __getattr__,__setattr__,__delattr。如下所示,还实现了只读的功能。

    class Circle(object):
        radius = 1.0
        def __getattr__(self,name):
            if name == 'area':
                return math.pi*self.radius**2
            elif name == 'perimeter':
                return 2*math.pi*self.radius
            else:
                return object.__getattr__(self,name)
        def __setattr__(self,name,value):
            if name in ['area','perimeter'] :
                raise TypeError("%s readonly" % name) 
            object.__setattr__(self,name,value)

     5) 元类 __metaclass__

      用来创建和管理类的对象。

    class DocMeta(type):
        def __init__(self,name,bases,dict):
            for key,value in dict.items():
                print key,value
                # 以"__"开始的 默认函数不检查
                if key.startswith("__"):continue
                # 仅检测可以调用  "__call__"  的函数
                if not hasattr(value,"__call__"):continue
                # 判断函数是否有说明文档 
                if not getattr(value,"__doc__"):
                    raise TypeError("%s must have a docstring" % key)
            type.__init__(self,name,bases,dict)
    class Circle(object):
        __metaclass__ = DocMeta

    6) 弱引用 weakref

      可以用来检测对象是否被正常释放。简单栗子如下:

    import weakref
    class LeakObserver(object):
        table_observers = []
        @classmethod
        def add(cls,obj): 
            "添加需要监听释放的对象"
            cls.table_observers.append(weakref.ref(obj))
        @classmethod
        def findLeak(cls):
            "查找未被正常释放对象"
            cls.table_observers = [ref for ref in cls.table_observers if ref()]
            print cls.table_observers
    a = Circle()
    LeakObserver.add(a)
    #del a
    LeakObserver.findLeak()
    协程

       通过在函数内使用yield语句的方式,称为协程。先执行next()或for循环才会时函数执行到yield语句。如果yield在左侧则循环生成列表返回,如果在右侧则挂起等待send()消息传入yield处。

    1) yield在左侧

    import os
    import fnmatch
    def find_files(topdir,pattern):
        for path,dirname,filelist in os.walk(topdir):
            for name in filelist:
                if fnmatch.fnmatch(name,pattern):
                    yield os.path.join(path,name)
    
    import gzip,bz2
    
    def opener(filenames):
        for name in filenames:
            if name.endswith(".gz"): f = gzip.open(name)
            elif name.endswith(".bz2"): f = bz2.BZ2File(name)
            else: f = open(name,"r")
            yield f
    def cat(filelist):
        for f in filelist:
            for line in f:
                yield line
    def grep(pattern,lines):
        for line in lines:
            if pattern in line:
                yield line
    
    debuglogs = 'debug.log'
    files   = opener(debuglogs)
    lines   = cat(files)
    pylines = grep("python",lines)
    for line in pylines:
        sys.stdout.write(line)

    在该栗子中,整个程序由最后的for语句驱动,中间不会产生临时列表等,占用内存极少。

    2)yield在右侧

    def receiver():
        print("ready to receiver")
        while True:
           n = (yield)
           print("Got %s" % n)
    r = receiver()
    r.next() r.send(
    "hello")

    执行next()后,函数执行到yield处。

    消息日志

       通过 import logging 来使用 logging模块记录日志。

    1) 基本配置

        通过 basicConfig设置默认的日志配置。如下:

    import logging
    logging.basicConfig(
        filename ="app.log",
        format   = "%(levelname)-10s %(asctime)s %(message)s",
        level    = logging.INFO
    )

    然后通过正常的logging记录如下:

    log = logging.getLogger('app')
    log.info("hello world")

    这样可以在 app.log文件中看到按format格式输出的记录了。

    2) 筛选日志

      通过addFilter,setLevel可以对单独的logging对象进行输出控制。如下:

    format = logging.Formatter("%(levelname)-10s %(asctime)s %(message)s")
    log = logging.getLogger('app.test')
    log.addHandler(logging.FileHandler('app.test.log'))     # 添加输出到文件
    stdout_hand = logging.StreamHandler(sys.stdout)         # 输出到控制台显示
    stdout_hand.setFormatter(format)                        # 设置输出格式
    log.addHandler(stdout_hand)                             # 添加输出Handler
    log.setLevel(logging.ERROR)                             # 设置消息级别
    log.info("info message!")
    log.log(logging.ERROR,"error message!")       

    这样控制台和app.test.log文件都会按格式输出错误消息!"ERROR      2016-03-28 10:29:28,651 error message!"

    而因为基础设置上的设置,app.log上会输出info和error的日志信息。

    3) 其他

    log.propagate = False            #禁止输出到父级log对象  'app.test'  -> ‘app’

    log.close()                            #关闭当前输出log对象

    命令行输入

       optparse模块处理sys.argv中提供的UNIX风格命令行选项高级支持。栗子如下:

    import optparse
    p = optparse.OptionParser()
    
    #简单项,不带参数
    p.add_option("-t",action = "store_true",dest = "tracing")
    #接受字符串参数
    p.add_option("-o","--outfile",action = "store", type = "string",dest= "outfile")
    #接收整数
    p.add_option("-d","--debuglevel",action = "store", type = "int",dest= "debug")
    #带选项参数
    p.add_option("--speed",action = "store" , type ="choice",dest="speed",choices=["slow","fast","ludicrous"])
    #多个参数
    p.add_option("--coord",action = "store", type="int", dest="coord",nargs =2)
    #一组控制常用目的地的选项
    p.add_option("--novice",action="store_const",const="novice",dest="mode")
    p.add_option("--guru",action="store_const",const="guru",dest="mode")
    #设置默认值
    p.set_defaults(tracing=False,debug=0,speed="fast",coor=(0,0),mode="novice")
    opt,args = p.parse_args()
    print opt,args

    可以通过输入test.py(文件名) -h参看说明。

    调优策略

      以下仅摘自参考手册并没有进行过系统测试。

    1、理解程序

      a、 理解算法

          b、使用内置类型

    2、不要添加层

    import timeit
    print timeit.timeit("s=  {'name':'GOOG','shares':100,'price':490.10}") #0.139700907932
    print timeit.timeit("s = dict(name='GOOG',shares=100,price = 490.10)") #0.341468762487

    3、了解如何基于字典构建类和实例

      如果值构建简单数据结构存储数据,字典比类可能更好。

    4、使用__slots__

      不实用字典(__dict__)存储实例数据,内存少,访问效率高。__slots__ =['name','shares','price']

    5、避免使用(.)运算符

    6、使用异常处理不常见的情况

      正常情况下不会抛出异常的代码设置try代码块比if语句速度更快。

    7、避免对常见情况使用异常

    #方法1
    try:
        value = items[key]
    except KeyError:
        value = None
    
    #方法2
    if key in items:
        value = items[key]
    else:
        value = None

       大部分是查找得到值的情况下,方法2运算是方法1的17倍。而且in运算符比方法调用(items.get(key))更快。

    8、鼓励使用函数编程和迭代

    9、使用装饰器和元类

  • 相关阅读:
    linux grep命令
    PHP 利用simplexml_load_file 读取XML对应的字段 然后存入mysql数据库
    php 设计模式之单类模式
    Mac C#开发工具Rider安利与环境配置教程
    模拟,贪心,枚举(二)
    模拟,贪心,枚举
    10.10 review
    review 10.9
    10.6 review
    9.28 review
  • 原文地址:https://www.cnblogs.com/stratrail/p/5318815.html
Copyright © 2011-2022 走看看