Sealyu

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

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            618 隨筆 :: 87 文章 :: 225 評論 :: 0 Trackbacks
          今天在啄木鳥社區(qū)看到這篇帖子,感覺挺簡潔的,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. 內建函數(shù)
              2. 切片
              3. 列表推導式
            4. 元組
            5. set
            6. dict
          4. 函數(shù)相關
            1. 函數(shù)定義 / 參數(shù)默認值
            2. Lambda函數(shù)
            3. 不定長參數(shù) *para,**para
            4. @ 裝飾器
            5. 生成器表達式
            6. yield
          5. 常用函數(shù)
            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反向循環(huán)
            15. sorted排序
            16. enumerate 返回索引位置和對應的值
            17. open/文件操作
          6. 模塊化
            1. 導入模塊
            2. 面向對象
              1. 概要
              2. 類繼承
              3. 多重繼承
            3. 操作符重載
              1. __str__ / __unicode__
              2. 比較操作
              3. __iter__
            4. 類相關函數(shù)
              1. type
              2. getattr / hasattr /delattr
              3. property
              4. isinstance( object, classinfo)
          7. Py常用模塊匯編

          簡述

          1. 閱讀須知

          文中使用

          >>>

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

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

          help(函數(shù)名)

          來獲取相關信息

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

          2. 基本語法

          2.1. if / elif / else

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

          if x>0:
          print '正數(shù)'
          elif x==0:
          print '零'
          else:
          print '負數(shù)'

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

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

          2.2. in

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

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

          2.3. for ... in

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

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

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

          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']

          若需要得到循環(huán)的次數(shù),參見 函數(shù) range 的用法

          2.4. break / continue

          這兩個的用法和C中相同

          for i in range(10):
          if 2==i:continue #結束當前循環(huán),進入下一步循環(huán)
          if 6==i:break #跳出循環(huán)
          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("請輸入數(shù)字:"))
          except ValueError: #可以同時捕獲多個異常,寫法如except(RuntimeError,ValueError):
          #當輸入非數(shù)字時
          print"您輸入不是數(shù)字"
          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 表示該值不存在,比如 沒有定義返回值 的函數(shù)就 返回None

          3.2. Ture / False

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

          3.3. List

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

          3.3.1. 內建函數(shù)

          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出現(xiàn)的次數(shù)

          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出現(xiàn)的次數(shù)
          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循環(huán)生成一個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]
          #循環(huán)變量要是一個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位小數(shù)(四舍五入)
          ['3.1', '3.14', '3.142', '3.1416', '3.14159']

          3.4. 元組

          一旦初始化便不能更改的數(shù)據結構,速度比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', #單個元素的元組,注意逗號

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

          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

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

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

          如果列表中存在關鍵字對,可以用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) #從序列生成并返回一個字典,其值為第二個參數(shù)(默認為None),不改變當前字典
          {1: 0, 2: 0}

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

          4. 函數(shù)相關

          4.1. 函數(shù)定義 / 參數(shù)默認值

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


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

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

          4.2. Lambda函數(shù)

          一種無名函數(shù)的速寫法

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

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

          4.3. 不定長參數(shù) *para,**para

          參數(shù)格式為 *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) 即將函數(shù)B作為參數(shù)傳給參數(shù)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. 生成器表達式

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

          >>>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

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

          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. 常用函數(shù)

          5.1. eval

          對字符串參數(shù)運算,求值

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

          5.2. exec

          將字符串參數(shù)作為python腳本執(zhí)行

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

          5.3. execfile

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

          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(類/函數(shù)) 返回相應對象的文檔字符串

          >>> 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) #小數(shù)輸出如 %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

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

          5.8. raw_input

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

          5.9. range

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

          和for...in配合使用

          a=['cat','door','example']
          for i in range(len(a)):#len()函數(shù)為求序列的長度
          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也要有相應多的參數(shù),如

          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

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

          5.13. zip

          zip用于多個sequence的循環(huán)

          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反向循環(huán)

          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") #如果要寫入字符串以外的數(shù)據,先將他轉換為字符串.

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

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

          用來移動文件指針

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

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

          f.close() 關閉文件

          6. 模塊化

          6.1. 導入模塊

          模塊的查找路徑

          1.當前的目錄

          2.環(huán)境變量PYTHONPATH所指的目錄列表

          3.python解釋器的安裝目錄

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

          import fibo
          fibo.function()

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

          f=fibo.function
          f()

          也可以

          form fibo import function
          function()

          甚至可以form fibo import * 

          可以 form 包.子包.模塊 imort 函數(shù) 

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

          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"]

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

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

          form 包.子包 imort 模塊

          簡寫為 imort 模塊

          6.3. 面向對象

          6.3.1. 概要

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

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

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

          6.3.2. 類繼承

          class DerivedClassName(BassClassName):

          • pass

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

          modname.BaseClassName

          派生類的函數(shù)會覆蓋基類的同名函數(shù)

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

          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

          對于該類函數(shù)的解析規(guī)則是深度優(yōu)先,先是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. 操作符重載

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

          6.4.1. __str__ / __unicode__

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

          str()函數(shù)的返回值.
          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) 用來簡化比較函數(shù)的定義 self < other返回負數(shù),相等時返回0,self>other時返回正數(shù)
          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 循環(huán)即就是通過這個函數(shù)遍歷當前容器的對象實例 可配合yield方便的編寫這個函數(shù)(參見基本語法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 

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

          6.5. 類相關函數(shù)

          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:通過類實例和一個字符串動態(tài)的調用類函數(shù)/屬性

          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 用來判斷實例有無該函數(shù)/屬性

          delattr 用來刪除實例的函數(shù)/屬性

          6.5.3. property

          通過值的方式調用實例無參函數(shù)

          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聯(lián)盟::

          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聯(lián)盟::

          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 壓縮, 減小數(shù)據庫文件體積,以改善磁盤 io 性能

          7.1.1. 發(fā)布

          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 倍

          發(fā)現(xiàn) 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 閱讀(1429) 評論(0)  編輯  收藏 所屬分類: Python
          主站蜘蛛池模板: 太仓市| 岑巩县| 宁安市| 资源县| 武山县| 渭南市| 文水县| 青铜峡市| 当涂县| 宁强县| 临洮县| 上高县| 许昌县| 游戏| 任丘市| 呼图壁县| 滦南县| 宿松县| 石家庄市| 太仆寺旗| 睢宁县| 长阳| 黄陵县| 宣威市| 江门市| 江都市| 手游| 建昌县| 嘉义县| 扶风县| 漳平市| 文化| 栖霞市| 汽车| 安丘市| 贺州市| 芒康县| 东山县| 靖安县| 福州市| 汝城县|