<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Sealyu

    --- 博客已遷移至: http://www.sealyu.com/blog

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      618 隨筆 :: 87 文章 :: 225 評論 :: 0 Trackbacks
    今天在啄木鳥社區看到這篇帖子,感覺挺簡潔的,mark一下:

    Python 絕對簡明手冊 -- zsp007@gmail.com ::-- ZoomQuiet [2006-09-15 04:35:33]

    Contents

    1. 閱讀須知
    2. 基本語法
      1. if / elif / else
      2. in
      3. for ... in
      4. break / continue
      5. while / pass
      6. is
      7. del
      8. try ... except ... finally / raise
    3. 內建類型
      1. None
      2. Ture / False
      3. List
        1. 內建函數
        2. 切片
        3. 列表推導式
      4. 元組
      5. set
      6. dict
    4. 函數相關
      1. 函數定義 / 參數默認值
      2. Lambda函數
      3. 不定長參數 *para,**para
      4. @ 裝飾器
      5. 生成器表達式
      6. yield
    5. 常用函數
      1. eval
      2. exec
      3. execfile
      4. dir
      5. help
      6. len
      7. print
      8. raw_input
      9. range
      10. filter
      11. map
      12. reduce
      13. zip
      14. reversed反向循環
      15. sorted排序
      16. enumerate 返回索引位置和對應的值
      17. open/文件操作
    6. 模塊化
      1. 導入模塊
      2. 面向對象
        1. 概要
        2. 類繼承
        3. 多重繼承
      3. 操作符重載
        1. __str__ / __unicode__
        2. 比較操作
        3. __iter__
      4. 類相關函數
        1. type
        2. getattr / hasattr /delattr
        3. property
        4. isinstance( object, classinfo)
    7. Py常用模塊匯編

    簡述

    1. 閱讀須知

    文中使用

    >>>

    作為會命令行中的輸出信息的前綴

    對于不清楚用用途的函數可以在解釋器下面輸入

    help(函數名)

    來獲取相關信息

    另外,自帶的文檔和google也是不可少的

    2. 基本語法

    2.1. if / elif / else

    x=int(raw_input("Please enter an integer:"))#獲取行輸入

    if x>0:
    print '正數'
    elif x==0:
    print '零'
    else:
    print '負數'

    此外C語言中類似"xxx?xxx:xxx"在Python中可以這樣寫

    >>>number=8
    >>>print "good" if 8==number else "bad" #當滿足if條件時返回"good",否則返回"bad"
    good

    2.2. in

    in判斷 一個數 是否在 一個集合(如:元組,列表等) 中

    if 'yes' in  ('y','ye','yes'):print  'ok'

    2.3. for ... in

    python中沒有類似C中的for循環,而是使用for...in來對集合中的每一個元素進行操作

    a=['cat','door','example']
    for x in a:
    print x

    如果要修改a的內容,請用a的副本循環(否則不安全),如:

    a=["cat","zsp007@gmail.com"]
    for x in a[:]:
    if len(x)>6:a.insert(0,x)
    >>>a
    ['zsp007@gmail.com', 'cat', 'zsp007@gmail.com']

    若需要得到循環的次數,參見 函數 range 的用法

    2.4. break / continue

    這兩個的用法和C中相同

    for i in range(10):
    if 2==i:continue #結束當前循環,進入下一步循環
    if 6==i:break #跳出循環
    print i

    輸出

    0
    1
    3
    4
    5

    2.5. while / pass

    while True:
    pass #什么也不做

    2.6. is

    用來比較兩個變量是否指向同一內存地址(也就是兩個變量是否等價) 而 == 是用來比較兩個變量是否邏輯相等

    a=[1,2]
    b=[1,2]
    >>> a is b
    False
    >>> a == b
    True

    2.7. del

    用于刪除元素

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

    del a[0]
    a
    >>>[2,3,4,5,6]

    del a[2:4]
    a
    >>>[2,3,6]

    del a[:]
    a
    >>>[]

    del a
    a
    #拋出異常
    >>>NameError: name 'a' is not defined

    2.8. try ... except ... finally / raise

    try ... except用于異常處理

    try:
    x=int(raw_input("請輸入數字:"))
    except ValueError: #可以同時捕獲多個異常,寫法如except(RuntimeError,ValueError):
    #當輸入非數字時
    print"您輸入不是數字"
    except: #省略異常名,可以匹配所有異常,慎用
    pass
    else:#當沒有異常時
    print 'result=',result
    finally:#和Java中類似。一般用于釋放資源,如文件,網絡連接。
    print 'finish'

    raise用于拋出異常,可以為自定義的異常類

    慣例是以Error結尾的類,同類的異常一般派生自同一個基類(如Exception)

    class MyError(Exception):
    def __init__(self,value):
    self.value=value
    def __str__(self):
    return reper(self.value)

    基類異??梢云ヅ渑缮惍惓?

    try:
    raise Exception("spam","egg")
    except Exception,inst:#inst為該異常類的實例,為可選項
    print type(inst) #異常的類型
    print inst

    3. 內建類型

    3.1. None

    None 表示該值不存在,比如 沒有定義返回值 的函數就 返回None

    3.2. Ture / False

    布爾類型,Ture等價于1,False等價于0

    3.3. List

    >>>test=[1,2,"yes"]

    3.3.1. 內建函數

    append(x) 追加到鏈尾

    extend(L) 追加一個列表,等價于+=

    insert(i,x) 在位置i插入x

    remove(x) 刪除第一個值為x的元素,如果不存在會拋出異常

    reverse() 反轉序列

    pop([i]) 返回并刪除位置為i的元素,i默認為最后一個元素(i兩邊的[]表示i為可選的,實際不用輸入)

    index(x) 返回第一個值為x的元素,不存在則拋出異常

    count(x) 返回x出現的次數

    sort() 排序

    例子:

    >>>test=[1,2,"yes"]

    >>>test.append(1) #追加到鏈尾
    >>>test
    [1, 2, 'yes', 1]

    >>>test.extend([ 'no','maybe']) #追加一個列表
    >>>test
    [1, 2, 'yes', 1, 'no', 'maybe']

    >>> test.insert(0,'never') #在位置0插入'never'
    >>> test
    ['never', 1, 2, 'yes', 1, 'no', 'maybe']

    >>> test.remove('no') #刪除第一個值為"no"的元素,如果不存在會拋出異常
    >>> test
    ['never', 1, 2, 'yes', 1, 'maybe']

    >>> test.reverse() #反轉序列
    >>> test
    ['maybe', 1, 'yes', 2, 1, 'never']

    >>> test.pop() #返回并刪除位置為i的元素,i默認為最后一個元素
    'never'
    >>> test
    ['maybe', 1, 'yes', 2, 1]

    >>> test.index('yes') #返回第一個值為'yes'的元素,不存在則拋出異常
    2

    >>> test.count(1) #返回1出現的次數
    2

    >>>test.sort() #排序
    >>> test
    [1, 1, 2, 'maybe', 'yes']

    3.3.2. 切片

    從序列中抽取一部分

    >>> test=['never', 1, 2, 'yes', 1, 'no', 'maybe']

    >>> test[0:3] #包括test[0],不包括test[3]
    ['never', 1, 2]

    >>> test[0:6:2] #包括test[0],不包括test[6],而且步長為2
    ['never', 2, 1]

    >>> test[:-1] #包括開始,不包括最后一個
    ['never', 1, 2, 'yes', 1, 'no']

    >>> test[-3:] #抽取最后3個
    [1, 'no', 'maybe']

    >>>test[::-1] #倒序排列
    ['maybe', 'no', 1, 'yes', 2, 1, 'never']

    3.3.3. 列表推導式

    可以直接通過for循環生成一個list

    >>>freshfruit=['  banana  ','   loganberry  ']
    >>>[weapon.strip() for weapon in freshfruit]
    ['banana', 'loganberry']

    說明:strip()是去除字符串兩端多于空格,該句是去除序列中的所有字串兩端多余的空格

    >>>vec=[2,4,6]
    >>>[3*x for x in vec if x>3]
    [12, 18]
    >>>[(x,x**2) for x in vec]
    #循環變量要是一個sequence,而[x,x**2 for x in vec]是錯誤的
    [(2,4),(4,16),(6,36)]
    >>>vec2=[4,3,-9]

    >>>[x*y for x in vec for y in vec2]
    [8, 6, -18, 16, 12, -36, 24, 18, -54]

    >>>[vec[i]+vec2[i] for i in range(len(vec))]
    [6, 7, -3]
    >>>[str(round(355/113.0,i)) for i in range(1,6)]
    #str()是轉換類型為可以打印的字符
    #round(x,n)表示對x保留n位小數(四舍五入)
    ['3.1', '3.14', '3.142', '3.1416', '3.14159']

    3.4. 元組

    一旦初始化便不能更改的數據結構,速度比list快

    >>>t=1234,5567,'hello' #t=(1234,5567,'hello')的簡寫

    >>>x,y,z=t #拆分操作可以應用于所有sequence
    >>>x
    1234

    >>>u=t,(1,2,3)
    >>>u
    ((1234,5567,'hello'),(1,2,3))

    >>>empty=() #空元組
    >>>singleton='hi', #單個元素的元組,注意逗號

    通過元組可以很簡單的進行數據交換. 比如:

    a=1
    b=2
    a,b=b,a

    3.5. set

    set(集合):無序不重復的元素集

    >>>basket = ['apple','orange','apple','pear','apple','banana']

    >>>fruit=set(basket)

    >>>fruit
    set(['orange', 'pear', 'apple', 'banana'])

    >>>'orange' in fruit
    True

    >>>a=set('abracadabew')
    >>>a
    set(['a', 'c', 'b', 'e', 'd', 'r', 'w'])

    >>>b=set('wajgwaoihwb')
    >>>b
    set(['a', 'b', 'g', 'i', 'h', 'j', 'o', 'w'])

    >>>a-b #差
    set(['c', 'r', 'e', 'd'])

    >>>a|b #并
    set(['a', 'c', 'b', 'e', 'd', 'g', 'i', 'h', 'j', 'o', 'r', 'w'])

    >>>a&b #交
    set(['a', 'b', 'w'])

    >>>a^b #(并-交)
    set(['c', 'e', 'd', 'g', 'i', 'h', 'j', 'o', 'r'])

    3.6. dict

    字典:關鍵字為不可變類型,如字符串,整數,只包含不可變對象的元組.

    列表等不可以作為關鍵字.

    如果列表中存在關鍵字對,可以用dict()直接構造字典.而這樣的列表對通常是由列表推導式生成的.

    >>>tel={'jack':4098,'sape':4139}

    >>>tel['guido']=4127

    >>>tel
    {'sape': 4139, 'jack': 4098, 'guido': 4127}

    >>>tel['jack'] #如果jack不存在,會拋出KeyError
    4098
    >>>a.get("zsp",5000) #如果"zsp"為tel的鍵則返回其值,否則返回5000

    >>>del tel['sape'] #刪除鍵'sape'和其對應的值
    >>>tel.keys() #復制一份鍵的副本,同理tel.items()為值的副本
    ['jack', 'guido']

    >>>"jack" in tel #判斷"jack"是否tel的鍵
    True
    >>>"zsp" not in tel
    True

    >>>for k,v in tel.iteritems():print k,v #同理tel.iterkeys()為鍵的迭代器,tel.itervalues()為值的迭代器
    jack 4098
    guido 4127

    >>>tel.copy() #復制一份tel
    {'jack': 4098, 'guido': 4127}

    >>> tel.fromkeys([1,2],0) #從序列生成并返回一個字典,其值為第二個參數(默認為None),不改變當前字典
    {1: 0, 2: 0}

    >>>tel.popitem() #彈出一項
    ('jack', 4098)

    4. 函數相關

    4.1. 函數定義 / 參數默認值

    def fib(n=2,a=1):#參數可以有默認值
    """這里給函數寫文檔注釋"""
    for i in range(n):
    print a


    >>>f=fib #可以用一個變量表示函數
    >>>f(3)
    1
    1
    1

    >>>fib(a=2) #多個可選參數賦值可以直接寫"參數變量名=值"來快速賦值
    2
    2

    4.2. Lambda函數

    一種無名函數的速寫法

    def make_incrementor(n):
    return lambda x: x+n

    f=make_incrementor(n)
    #f等價于
    #def f(x):
    # return x+n

    4.3. 不定長參數 *para,**para

    參數格式為 *para 表示接受一個元組

    為 **para 表示接受一個字典

    *para要在**para之前

    def test(*args,**dic):
    for arg in args :
    print arg
    for k,v in dic.iteritems():
    print k ,':',v

    >>> test("yes",1,2,me="張沈鵬",where="中國") #"yes",1,2傳遞給元組;me="張沈鵬",where="中國"傳遞給字典
    yes
    1
    2
    me : 張沈鵬
    where : 中國

    4.4. @ 裝飾器

    @A def B:pass 等價于 def B:pass B=A(B) 即將函數B作為參數傳給參數A

    from time import time
    #測試運行時間
    def cost_time(func):
    def result(*args,**dic):
    beign=time()
    func(*args,**dic)
    print "cost time : ",time()-beign
    return result

    @cost_time
    def show(n):
    for x in range(n):print x

    >>> show(10)
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    cost time : 0.0469999313354

    4.5. 生成器表達式

    生成器表達式:類似于沒有中括號的列表推導式,可用在參數中

    >>>sum(i*i for i in range(10))
    285

    >>>unique_words=set(word for line in page for word in line.split())#page為打開的文件

    >>>data='golf'

    >>>list(data[i] for i in range(len (data)-1,-1,-1))
    ['f','l','o','g']

    4.6. yield

    每次調用返回一個值,并記錄當前執行位置所有的變量

    def reverse(data):
    for index in range(len(data)-1,-1,-1):
    yield data[index]

    for char in reverse("golf"):
    print char,

    輸出

    f l o g

    5. 常用函數

    5.1. eval

    對字符串參數運算,求值

    >>> eval("1 + 2*3") #可以方便的用來做四則運算
    7
    >>> a=1
    >>> eval('a+1') #可以訪問變量
    2

    5.2. exec

    將字符串參數作為python腳本執行

    >>> exec('a="Zsp"')
    >>> a
    'Zsp'

    5.3. execfile

    和exec類似,不過是用來打開一個文件,并作為python腳本執行

    5.4. dir

    顯示對象的所有屬性(即可以用"."操作直接訪問)

    >>> dir([])
    ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__delslice__', '__doc__', '__eq__', '__ge__', '__getattribute__', '__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__setslice__', '__str__', 'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

    5.5. help

    help(類/函數) 返回相應對象的文檔字符串

    >>> help(vars)
    Help on built-in function vars in module __builtin__:

    vars(...)
    vars([object]) -> dictionary

    Without arguments, equivalent to locals().
    With an argument, equivalent to object.__dict__.

    5.6. len

    返回序列/字典的長度

    >>> len([1,2,3])
    3

    5.7. print

    輸出字符串 用法演示:

    print "Today ", #加逗號,輸出后不換行

    name="ZSP"

    print name,"cost $",10 #輸出多個變量

    print "hello,%s!"%name #%s 表示用str轉化為字符串

    for x in xrange(1,11):
    print '%2d %3d' % (x,x*x) #小數輸出如 %5.3f

    對于字典可以用變量名來直接格式化,如:

    >>>table={'Sjoerd':4127,'Jack':4098,'Dcab':8637678}
    >>>print 'Jack:%(Jack)d; Sjoerd:%(Sjoerd)d; Dcab:%(Dcab)d' %
    table
    Jack:4098; Sjoerd:4127; Dcab:8637678

    同時,函數vars()返回包含所有變量的字典,配合使用,無堅不摧!

    5.8. raw_input

    x=raw_input("Please enter an sentence:") #將輸入的內容賦值給x

    5.9. range

    range(10,0,-3)#參數的含義為起點(默認為0),終點(不含終點),步長(默認為1)
    >>>[10,7,4,1]

    和for...in配合使用

    a=['cat','door','example']
    for i in range(len(a)):#len()函數為求序列的長度
    print i,a[i]

    5.10. filter

    filter(function , sequence) 返回序列,為原序列中能使function返回true的值

    >>>a=[1,2,3,4]
    >>>filter(lambda x:x%2,a)
    [1, 3]

    5.11. map

    map(function,sequence,[sequence...])

    返回序列,為對原序列每個元素分別調用function獲得的值.

    可以傳入多個序列,但function也要有相應多的參數,如

    map(lambda x,y,z:x+y+z,range(1,3),range(3,5),range(5,7))

    計算過程為

    1+3+5=9

    2+4+6=12

    返回[9,12]

    5.12. reduce

    reduce(function,sequence,[init])

    返回一個單值為,計算步驟為 :

    • 第1個結果=function(sequence[0],sequence[1])
    • 第2個結果=function(第1個結果,sequence[2])
    • 返回最后一個計算得值
    • 如果有init,則先調用function(init,sequence[0]) 

    • sequence只有一個元素時,返回該元素,為空時拋出異常.

    reduce(lambda x,y:x+y,range(3),99) 的計算為

    99+0=99 => 99+1=100 => 100+2=102

    返回102

    注:實際使用中用內建函數sum來完成這個累加更合適,如這里等價sum(range(3),99)

    5.13. zip

    zip用于多個sequence的循環

    questions=['name','quest','favorite color']
    answers=['lancelot','the holy grail','blue']

    for q,a in zip(questions,answers):
    print 'What is your %s ? It is %s.'%(q,a)

    輸出:

    What is your name ? It is lancelot.
    What is your quest ? It is the holy grail.
    What is your favorite color ? It is blue.

    5.14. reversed反向循環

    for i in reversed(range(1,4)):
    print i

    輸出:

    3
    2
    1

    5.15. sorted排序

    返回一個有序的新序列

    >>>sorted([2,5,1,4])
    [1, 2, 4, 5]

    5.16. enumerate 返回索引位置和對應的值

    for i,v in enumerate(['tic','tac','toe'])
    print i,v

    輸出:

    0 tic
    1 tac
    2 toe

    5.17. open/文件操作

    f=open('/tmp/hello','w')

    #open(路徑+文件名,讀寫模式)

    #讀寫模式:r只讀,r+讀寫,w新建(會覆蓋原有文件),a追加,b二進制文件.常用模式

    如:'rb','wb','r+b'等等

    f.read([size]) size未指定則返回整個文件,如果文件大小>2倍內存則有問題.f.read()讀到文件尾時返回""(空字串)

    file.readline() 返回一行

    file.readline([size]) 返回包含size行的列表,size 未指定則返回全部行

    for line in f: print line #通過迭代器訪問

    f.write("hello"n") #如果要寫入字符串以外的數據,先將他轉換為字符串.

    f.tell() 返回一個整數,表示當前文件指針的位置(就是到文件頭的比特數).

    f.seek(偏移量,[起始位置])

    用來移動文件指針

    偏移量:單位:比特,可正可負

    起始位置:0-文件頭,默認值;1-當前位置;2-文件尾

    f.close() 關閉文件

    6. 模塊化

    6.1. 導入模塊

    模塊的查找路徑

    1.當前的目錄

    2.環境變量PYTHONPATH所指的目錄列表

    3.python解釋器的安裝目錄

    如將代碼保存上述的一個目錄中的的fibo.py文件中,便可以

    import fibo
    fibo.function()

    如果想直接使用fibo.function可以重命名這個函數,如

    f=fibo.function
    f()

    也可以

    form fibo import function
    function()

    甚至可以form fibo import * 

    可以 form 包.子包.模塊 imort 函數 

    然后就直接使用該函數,不需要加前綴

    6.2. 包

    引用推薦寫法為

    form 包 import 模塊

    幾個功能類似的模塊可以組合成一個包,

    比如一個可以處理.wav,.mp3,.wma等音頻文件的有類似如下結構:

    Sound/
    __init__.py
    Formats/
    __init__.py
    wavread.py
    wavwrite.py
    mp3read.py
    mp3write.py
    wmaread.py
    wmawrite.py
    Effects/
    __init__.py
    echo.py
    surround.py
    reverse.py

    只有當init.py存在時python才將該文件夾視為一個包.

    該文件可以為空文件 一般在init.py文件中定義一個all列表,包含要import *時要導入的模塊. 如Sound/Effects/init.py可以有如下內容

    __all__=["echo","surround","reverse"]

    包的作者在發布包時可以更新這個列表,也可以根據需要讓某個模塊不支持import *

    對于包中同一個文件夾下的模塊可以把

    form 包.子包 imort 模塊

    簡寫為 imort 模塊

    6.3. 面向對象

    6.3.1. 概要

    class ClassName:
    "類文檔,可以通過類名.__doc__訪問"
    def f(self):#self為每個類函數的必要的一個參數,可以通過它來訪問當前實例
    return self.content

    def __init__(self,word=''):#構造函數
    #構造函數,可以初始化變量,可以有參數"
    self.content=word
    self.__name=word #私有變量,以"__"開頭,不以"__"結尾的變量

    創建類實例 x=ClassName("good")

    6.3.2. 類繼承

    class DerivedClassName(BassClassName):

    • pass

    如果基類定義在另一個模塊中, 要寫成

    modname.BaseClassName

    派生類的函數會覆蓋基類的同名函數

    如果想擴充而不是改寫基類的函數,可以這樣調用基類函數

    BaseClassName.methodname(self,arguments)

    注意:該基類要在當前全局域或被導入

    class A:
    def hi(self):
    print "A"
    class B:
    def hi(self):
    A.hi(self)
    super(B).hi() #通過super關鍵字可以獲得當前類的基類
    print "B"

    B().hi()

    輸出

    A
    B

    6.3.3. 多重繼承

    類多繼承

    class DerivedClassName(Base1,Base2,Base3):
    pass

    對于該類函數的解析規則是深度優先,先是Base1,然后是Base1的基類,諸如此類.

    class A:
    def hi(self):
    print "A"

    class B:
    def hi(self):
    print "B"

    class C(A,B):
    pass

    C().hi()

    輸出:

    A

    6.4. 操作符重載

    通過定義類的一些約定的以""開頭并結尾的函數,可以到達重載一些特定操作的目的,下面是是一些常用的重載

    6.4.1. __str__ / __unicode__

    當print一個對象實例時,實際是print該實例

    str()函數的返回值.
    class A:
    def __str__(self):
    return "A"
    def __unicode__(self):
    return "uA"

    print A()
    print unicode(A())

    輸出

    A
    uA
    unicode和str類似,不過返回Unicode字符串.

    6.4.2. 比較操作

    x<y x.

    lt(y)

    x<=y x.

    le(y)

    x==y x.

    eq(y)

    x!=y 或 x<>y x.

    ne(y)

    x>y x.

    gt(y)

    x>=y x.

    ge(y) cmp( self, other) 用來簡化比較函數的定義 self < other返回負數,相等時返回0,self>other時返回正數
    class A:
    def __init__(self,i):
    self.i=i
    def __cmp__(self,other):
    return self.i-other.i

    print A(1)>A(2)

    輸出

    False

    6.4.3. __iter__

    for ... in 循環即就是通過這個函數遍歷當前容器的對象實例 可配合yield方便的編寫這個函數(參見基本語法yield)

    class A:
    def __init__(self,n):
    self.n=n
    def __iter__(self):
    n=self.n
    while n:
    m=n%2
    n/=2
    yield m

    for i in A(5):
    print i,

    輸出

    1 0 1 

    另有一種繁瑣的實現: 返回一個可以通過next()函數遍歷的對象,當結束時拋出StopIteration異常

    6.5. 類相關函數

    6.5.1. type

    返回對象的類型

    >>> type("")
    <type 'str'>
    >>> type("")==str
    True

    >>> type([])
    <type 'list'>
    >>> type([])==list
    True

    >>> type({})
    <type 'dict'>

    >>> type(())
    <type 'tuple'>

    >>> class A:pass

    >>> type(A)
    <type 'classobj'>

    >>> type(A())
    <type 'instance'>

    >>> import types #在types模塊中有許多類型的定義

    >>> type(A)==types.ClassType
    True

    6.5.2. getattr / hasattr /delattr

    getattr:通過類實例和一個字符串動態的調用類函數/屬性

    class A:
    def name(self):
    return "ZSP"
    def hello(self):
    return "nice to meet me ."

    def say(obj,attr):
    print getattr(obj,attr)()

    a=A()
    say(a,"name")
    say(a,"hello")

    輸出

    ZSP
    nice to meet me .

    hasattr 用來判斷實例有無該函數/屬性

    delattr 用來刪除實例的函數/屬性

    6.5.3. property

    通過值的方式調用實例無參函數

    class A(object):
    def __init__(self): self._x = None
    def getx(self): return self._x
    def setx(self, value): self._x = value
    def delx(self): self._x=None
    x = property(getx, setx, delx, "I'm the 'x' property.")
    a=A()
    print a.x

    a.x="ZSP"
    print a.x

    del a.x
    print a.x

    輸出

    None
    ZSP
    None

    可以方便的定義一個只讀屬性

    class A(object):
    @property
    def x(self): return "Property"

    調用

    >>>a=A()

    >>>print a.x
    Property

    >>>a.x="ZSP" #只讀屬性,不能更改
    Traceback (most recent call last):
    File "D:"Profile"Untitled 2.py", line 9, in <module>
    a.x="ZSP"
    AttributeError: can't set attribute

    6.5.4. isinstance( object, classinfo)

    判斷一個對象是否是一個類的實例

    >>>class A:pass

    >>>class B:pass

    >>>a=A()

    >>>isinstance(a,A)
    True

    >>>isinstance(a,B)
    False

    Python 常用模塊體驗 ::-- ZoomQuiet [2007-11-10 06:37:48]

    CPUG聯盟::

    CPUG::門戶plone

    BPUG

    SPUG

    ZPUG

    SpreadPython Python宣傳

    7. Py常用模塊匯編

    'Python 標準庫2.0 整理者

    Python 江湖 QQ 群: 43680167
    Feather (校對) gt: andelf@gmail.com

    ::-- ZoomQuiet [2007-11-10 07:39:01]

    CPUG聯盟::

    CPUG::門戶plone

    BPUG

    SPUG

    ZPUG

    SpreadPython Python宣傳

    7.1. zshelve 對象持久模塊

    Jiahua Huang <jhuangjiahua@gmail.com> 
    reply-to python-cn@googlegroups.com,
    to "python. cn" <python-cn@googlegroups.com>,
    date Nov 8, 2007 5:41 PM
    subject [CPyUG:34726] 貼個 zlib 壓縮的 zshelve 對象持久模塊

    這個給 Python 標準庫的 shelve.py 添加了 zlib 壓縮, 減小數據庫文件體積,以改善磁盤 io 性能

    7.1.1. 發布

    http://zshelve.googlecode.com/svn/trunk/

    加了個命令行工具:

    huahua@huahua:tmp$ zshelve
    commandline tool for zshelve databases

    Usage: zshelve FILE dump Dump the data tree
    zshelve FILE keys List of keys
    zshelve FILE get KEY Dump value for key
    zshelve FILE set KEY VALUE Set db[key] = value
    zshelve FILE has_key KEY True if database has the key
    zshelve FILE search_key KEY Search key
    zshelve FILE search_value VALUE Search value

    huahua@huahua:tmp$ zshelve set tes.db a 1
    huahua@huahua:tmp$ zshelve dump tes.db
    |- a
    | | - 1
    huahua@huahua:tmp$ zshelve set tes.db b "dict(a=1,b=2,c=3,d={'s':'4'})"
    huahua@huahua:tmp$ zshelve dump tes.db
    |- a
    | |- 1
    |- b
    | |- a
    | | |- 1
    | |- c
    | | |- 3
    | |- b
    | | |- 2
    | |- d
    | | |- s
    | | | |- 4

    對比::

    >>> import zshelve
    >>> import shelve
    >>> zdb = zshelve.open('/tmp/zshelve.db')
    >>> db = shelve.open('/tmp/shelve.db')
    >>> zdb['1'] = dict(a='0123456789'*10000000)
    >>> db['1'] = dict(a='0123456789'*10000000)
    >>> zdb.sync()
    >>> db.sync()

    看看文件大小差異::

    huahua@huahua:zshelve$ ll /tmp/*shelve.db
    -rw-r--r-- 1 huahua huahua 96M 2007-11-08 17:36 /tmp/shelve.db
    -rw-r--r-- 1 huahua huahua 204K 2007-11-08 17:36 /tmp/zshelve.db

    7.1.2. 補丁::

    --- shelve.py   2007-05-03 00:56:36.000000000 +0800
    +++ zshelve.py 2007-11-08 17:25:59.000000000 +0800
    @@ -70,6 +70,7 @@ except ImportError:

    import UserDict
    import warnings
    +import zlib ## use zlib to compress dbfile

    __all__ = ["Shelf","BsdDbShelf","DbfilenameShelf","open"]

    @@ -80,13 +81,14 @@ class Shelf(UserDict.DictMixin):
    See the module's __doc__ string for an overview of the interface.
    """

    - def __init__(self, dict, protocol=None, writeback=False):
    + def __init__(self, dict, protocol=None, writeback=False, compresslevel=2):
    self.dict = dict
    if protocol is None:
    protocol = 0
    self._protocol = protocol
    self.writeback = writeback
    self.cache = {}
    + self.compresslevel = compresslevel

    def keys(self):
    return self.dict.keys()
    @@ -109,7 +111,7 @@ class Shelf(UserDict.DictMixin):
    try:
    value = self.cache[key]
    except KeyError:
    - f = StringIO(self.dict[key])
    + f = StringIO(zlib.decompress(self.dict[key]))
    value = Unpickler(f).load()
    if self.writeback:
    self.cache[key] = value
    @@ -121,7 +123,7 @@ class Shelf(UserDict.DictMixin):
    f = StringIO()
    p = Pickler(f, self._protocol)
    p.dump(value)
    - self.dict[key] = f.getvalue()
    + self.dict[key] = zlib.compress(f.getvalue(), self.compresslevel)

    def __delitem__(self, key):
    del self.dict[key]
    @@ -168,32 +170,32 @@ class BsdDbShelf(Shelf):
    See the module's __doc__ string for an overview of the interface.
    """

    - def __init__(self, dict, protocol=None, writeback=False):
    - Shelf.__init__(self, dict, protocol, writeback)
    + def __init__(self, dict, protocol=None, writeback=False, compresslevel=2):
    + Shelf.__init__(self, dict, protocol, writeback, compresslevel)

    def set_location(self, key):
    (key, value) = self.dict.set_location(key)
    - f = StringIO(value)
    + f = StringIO(zlib.decompress(value))
    return (key, Unpickler(f).load())

    def next(self):
    (key, value) = self.dict.next()
    - f = StringIO(value)
    + f = StringIO(zlib.decompress(value))
    return (key, Unpickler(f).load())

    def previous(self):
    (key, value) = self.dict.previous()
    - f = StringIO(value)
    + f = StringIO(zlib.decompress(value))
    return (key, Unpickler(f).load())

    def first(self):
    (key, value) = self.dict.first()
    - f = StringIO(value)
    + f = StringIO(zlib.decompress(value))
    return (key, Unpickler(f).load())

    def last(self):
    (key, value) = self.dict.last()
    - f = StringIO(value)
    + f = StringIO(zlib.decompress(value))
    return (key, Unpickler(f).load())


    @@ -204,12 +206,12 @@ class DbfilenameShelf(Shelf):
    See the module's __doc__ string for an overview of the interface.
    """

    - def __init__(self, filename, flag='c', protocol=None, writeback=False):
    + def __init__(self, filename, flag='c', protocol=None,
    writeback=False, compresslevel=2):
    import anydbm
    - Shelf.__init__(self, anydbm.open(filename, flag), protocol, writeback)
    + Shelf.__init__(self, anydbm.open(filename, flag), protocol,
    writeback, compresslevel)


    -def open(filename, flag='c', protocol=None, writeback=False):
    +def open(filename, flag='c', protocol=None, writeback=False, compresslevel=2):
    """Open a persistent dictionary for reading and writing.

    The filename parameter is the base filename for the underlying
    @@ -222,4 +224,4 @@ def open(filename, flag='c', protocol=No
    See the module's __doc__ string for an overview of the interface.
    """

    - return DbfilenameShelf(filename, flag, protocol, writeback)
    + return DbfilenameShelf(filename, flag, protocol, writeback, compresslevel)

    ::-- ZoomQuiet [2007-11-10 07:34:49]

    Contents

    1. fast UserDict

    7.2. fast UserDict

    Jiahua Huang <jhuangjiahua@gmail.com> 
    reply-to python-cn@googlegroups.com,
    to "python. cn" <python-cn@googlegroups.com>,
    date Nov 10, 2007 3:28 PM
    subject [CPyUG:34791] 一行代碼讓 UserDict.UserDict 的類加速 4 倍

    發現 Python 標準庫里好些字典類從 UserDict.UserDict 派生, 而不是從 dict 派生, 是因為 舊版 python 內建類型不能派生子類,

    那么這會不會影響速度呢,

    先給兩個分別繼承 UserDict.UserDict 和 dict 的類 URdict, Rdict

    >>> import UserDict
    >>> class URdict(UserDict.UserDict):
    ... '''dict can search key by value
    ... '''
    ... def indexkey4value(self, value):
    ... '''search key by value
    ... >>> rd = Rdict(a='One', b='Other', c='What', d='Why', e='Other')
    ... >>> rd.indexkey4value('Other')
    ... 'b'
    ... '''
    ... try:
    ... ind = self.values().index(value)
    ... return self.keys()[ind]
    ... except:
    ... return None
    ... def key4value(self, svalue):
    ... '''search key by value
    ... >>> rd = Rdict(a='One', b='Other', c='What', d='Why', e='Other')
    ... >>> rd.key4value('Other')
    ... 'b'
    ... '''
    ... for key, value in self.iteritems():
    ... if value == svalue:
    ... return key
    ... def keys4value(self, svalue):
    ... '''search keys by value
    ... >>> rd = Rdict(a='One', b='Other', c='What', d='Why', e='Other')
    ... >>> rd.keys4value('Other')
    ... ['b', 'e']
    ... '''
    ... keys=[]
    ... for key, value in self.iteritems():
    ... if value == svalue:
    ... keys.append(key)
    ... return keys
    ...
    >>>
    >>> class Rdict(dict):
    ... '''dict can search key by value
    ... '''
    ... def indexkey4value(self, value):
    ... '''search key by value
    ... >>> rd = Rdict(a='One', b='Other', c='What', d='Why', e='Other')
    ... >>> rd.indexkey4value('Other')
    ... 'b'
    ... '''
    ... try:
    ... ind = self.values().index(value)
    ... return self.keys()[ind]
    ... except:
    ... return None
    ... def key4value(self, svalue):
    ... '''search key by value
    ... >>> rd = Rdict(a='One', b='Other', c='What', d='Why', e='Other')
    ... >>> rd.key4value('Other')
    ... 'b'
    ... '''
    ... for key, value in self.iteritems():
    ... if value == svalue:
    ... return key
    ... def keys4value(self, svalue):
    ... '''search keys by value
    ... >>> rd = Rdict(a='One', b='Other', c='What', d='Why', e='Other')
    ... >>> rd.keys4value('Other')
    ... ['b', 'e']
    ... '''
    ... keys=[]
    ... for key, value in self.iteritems():
    ... if value == svalue:
    ... keys.append(key)
    ... return keys
    ...
    >>>

    >>> import time
    >>> def _timeit(_src):
    ... exec('''
    ... _t0 = time.time()
    ... %s
    ... _t1 = time.time()
    ... _t3 = _t1 - _t0
    ... '''%_src)
    ... return _t3
    ...
    >>> ran = range(100000)

    再弄倆實例
    >>> u = URdict()
    >>> r = Rdict()

    看看插入速度
    >>> _timeit("for i in ran: u[i]=i")
    0.1777961254119873
    >>> _timeit("for i in ran: r[i]=i")
    0.048948049545288086

    看看原始 dict 的速度
    >>> _timeit("for i in ran: d[i]=i")
    0.041368961334228516

    可以看到, UserDict.UserDict 確實嚴重影響速度,

    python 標準庫里邊好多 UserDict 的都應該換成 dict , 以提高性能

    不過,一個個修改 Python 標準庫似乎又不合適,

    再次使用一招鮮,直接干掉 UserDict

    在使用/導入那些模塊前先來一行

    >>> import UserDict; UserDict.UserDict = dict

    完了再導入模塊來試試

    >>> u = URdict()
    >>> _timeit("for i in ran: u[i]=i")
    0.042366981506347656

    一行代碼讓速度提高 4 倍



    posted on 2008-12-29 14:50 seal 閱讀(1426) 評論(0)  編輯  收藏 所屬分類: Python
    主站蜘蛛池模板: 伊人久久亚洲综合| 好爽好紧好大的免费视频国产| 亚洲成av人在片观看| 亚洲sm另类一区二区三区| 永久免费的网站在线观看| 亚洲伊人久久大香线蕉| 久久精品网站免费观看| 亚洲精品国产av成拍色拍| 国产成人aaa在线视频免费观看| 18禁亚洲深夜福利人口| 九月婷婷亚洲综合在线| 小日子的在线观看免费| 无码专区—VA亚洲V天堂| 亚洲成人在线免费观看| 亚洲午夜一区二区三区| 日本免费v片一二三区| 一级片在线免费看| 亚洲成a人片在线观看无码 | 永久免费精品影视网站| 国产午夜亚洲不卡| 性xxxx视频免费播放直播| 亚洲二区在线视频| 四虎永久在线精品免费影视| 一区二区三区免费精品视频| 亚洲AV日韩AV鸥美在线观看| 在线观看视频免费完整版 | 一级毛片免费不卡直观看| 亚洲精品国产精品乱码不卡√| 日韩精品无码一区二区三区免费 | 亚洲日韩精品无码专区加勒比| 免费在线观看日韩| 久久成人无码国产免费播放| 免费在线观看黄色毛片| 国产精品福利片免费看| 亚洲国产一区在线观看| www.91亚洲| 久久精品免费一区二区| 免费播放国产性色生活片| 亚洲高清中文字幕综合网| 免费人成视频在线观看不卡| 99在线免费观看视频|