好全面的python筆記,那我就笑納了

注:本筆記基於python2.6而編輯,儘量的偏向3.x的語法



Python的特色

  1.簡單

  2.易學

  3.免費、開源

  4.高層語言: 封裝內存管理等

  5.可移植性: 程序如果避免使用依賴於系統的特性,那麼無需修改就可以在任何平臺上運行

  6.解釋性: 直接從源代碼運行程序,不再需要擔心如何編譯程序,使得程序更加易於移植。

  7.面向對象: 支持面向過程的編程也支持面向對象的編程。

  8.可擴展性: 需要保密或者高效的代碼,可以用C或C++編寫,然後在Python程序中使用它們。

  9.可嵌入性: 可以把Python嵌入C/C++程序,從而向你的程序用戶提供腳本功能。

  10.豐富的庫: 包括正則表達式、文檔生成、單元測試、線程、數據庫、網頁瀏覽器、CGI、FTP、

     電子郵件、XML、XML-RPC、HTML、WAV文件、密碼系統、GUI(圖形用戶界面)、Tk和其他與系統有關的操作。

     除了標準庫以外,還有許多其他高質量的庫,如wxPython、Twisted和Python圖像庫等等。

  11.概括: Python確實是一種十分精彩又強大的語言。它合理地結合了高性能與使得編寫程序簡單有趣的特色。

  12.規範的代碼: Python採用強制縮進的方式使得代碼具有極佳的可讀性。



Python 下載地址

    http://www.python.org/download/


Python 安裝:

    windows時,運行安裝文件之後,還需要配置環境變量,在環境變量的“Path”後面加上英文的分號及python安裝目錄

    如:“;C:\promg\python2.6”

    不配置環境變量的話,沒法在命令行直接使用python


有兩種使用Python運行你的程序的方式

   1.使用交互式的帶提示符的解釋器

     直接雙擊運行“python.exe”,在裏面輸入內容,如: print 'haha...'

   2.使用源文件

     在Python的安裝目錄下,建一個批處理(test.bat),寫入:

     @echo off

     python.exe test.py

     pause


     而“test.py”裏面的內容是需要執行的程序



Python命令行選項

    選項      作用

    -c cmd   在命令行直接執行python代碼。如python -c 'print "hello world"'。

    -d       腳本編譯後從解釋器產生調試信息。同PYTHONDEBUG=1。

    -E       忽略環境變量。

    -h       顯示python命令行選項幫助信息。

    -i       腳本執行後馬上進入交互命令行模式。同PYTHONINSPECT=1。

    -O       在執行前對解釋器產生的字節碼進行優化。同 PYTHONOPTIMIZE=1。

    -OO      在執行前對解釋器產生的字節碼進行優化,並刪除優化代碼中的嵌入式文檔字符串。

    -Q arg   除法規則選項,-Qold(default),-Qwarn,-Qwarnall,-Qnew。

    -S       解釋器不自動導入site.py模塊。

    -t       當腳本的tab縮排格式不一致時產生警告。

    -u       不緩衝stdin、stdout和stderr,默認是緩衝的。同PYTHONUNBUFFERED=1。

    -v       產生每個模塊的信息。如果兩個-v選項,則產生更詳細的信息。同PYTHONVERBOSE=x。

    -V       顯示Python的版本信息。

    -W arg   出錯信息控制。(arg is action:message:category:module:lineno)

    -x       忽略源文件的首行。要在多平臺上執行腳本時有用。

    file     執行file裏的代碼。

    -        從stdin裏讀取執行代碼。



easy_install

    這是個很常用的python安裝工具

    可以直接安裝ez_setup.py腳本(下載網址: http://peak.telecommunity.com/dist/ez_setup.py):

        python ez_setup.py


    windows 下的使用:

      安裝:

        下載: http://peak.telecommunity.com/dist/ez_setup.py

        執行: python ez_setup.py

      使用:

        easy_install.exe -U %modal%  # %modal% 是模塊名


    linux 下:

      安裝:

        sudo apt-get install python-setuptools

      或者:

        wget -q http://peak.telecommunity.com/dist/ez_setup.py

        sudo python ez_setup.py

      使用:

        sudo easy_install 模塊名


        安裝完後,最好確保easy_install所在目錄已經被加到PATH環境變量裏:

        Windows: C:\Python25\Scripts

        Linux: /usr/local/bin


    不能使用easy_install的特殊情況:

        a、安裝默認版本的MySQL-python會報錯,需要指定版本如下:easy_install "MySQL-python==1.2.2"

        b、有些包直接easy_install會失敗,需要自行下載安裝:

           wxpython,pil要下載exe安裝程序

           robotide因爲在pypi上找不到,要下載後再easy_install


    通過easy_install安裝軟件,相關安裝信息會保存到easy-install.pth文件裏,路徑類似如下形式:

    Windows:C:\Python25\Lib\site-packages\easy-install.pth

    Linux:/usr/local/lib/python25/site-packages/easy-install.pth


    如果想刪除通過easy_install安裝的軟件包,比如說:MySQL-python,可以執行命令:

        easy_install -m MySQL-python


    此操作會從easy-install.pth文件裏把MySQL-python的相關信息抹去,剩下的egg文件,你可以手動刪除。



版本問題

   python3.0版本較之前的有很大變動,而且不向下兼容。

   Python 2.6作爲一個過渡版本,基本使用了Python 2.x的語法和庫,同時考慮了向Python 3.0的遷移。即2.6版本兼容2.x和3.0的語法

       Python 2.6保持了對之前版本的全兼容,而且還包含了Python 3.0的新玩意(一些新特性需要通過“from __future__ import”來啓用)。

       如,在Python2.6要使用3.0的打印,得寫上“ from __future__ import print_function”

   基於早期Python版本而能正常運行於Python 2.6並無警告的程序可以通過一個2 to 3的轉換工具無縫遷移到Python 3.0。


   部分函數和語句的改變

      最引人注意的改變是print語句沒有了,取而代之的是print函數

      同樣的還有exec語句,已經改爲exec()函數。去除了<>,全部改用!=。

        在python2.x版本中

          #!/usr/bin/env python

          # 或者上句寫: #!/usr/bin/python

          print "Hello, world!"

          或者:

          import sys

          sys.stdout.write("Hello, world\n")


        在python3.x中

          print('Hello world!')

   用迭代器來替代列表

      一些知名的API將不再返回列表。

      而字典的dict.iterkeys()、dict.itervalues()和dict.iteritems()方法將會移除,而你可以使用.keys()、.values()和.items(),它們會返回更輕量級的、類似於集合的容器對象,而不是返回一個列表來複制鍵值。

      這樣做的優點是,可以直接在鍵和條目上進行集合操作,而不需要再複製一次。

   整型數

      移除了含糊的除法符號('/'),而只返回浮點數。

      在以前的版本中,如果參數是int或者是long的話,就會返回相除後結果的向下取整(floor),而如果參數是float或者是complex的話,那麼就會返回相除後結果的一個恰當的近似。

      在2.6版本中可以通過from __future__ import division來啓用這項特性。



python2 to python3 問題

    1.print 語句

           2.x                        3.x                           說明

       ① print                      print()                      # 輸出一個空白行

       ② print 1                    print(1)                     # 輸出一個單獨的值

       ③ print 1, 2                 print(1, 2)                  # 輸出多個值,以空格分割

       ④ print 1, 2,                print(1, 2, end=' ')         # 輸出時取消在末尾輸出回車符。

       ⑤ print >>sys.stderr, 1, 2   print(1, 2, file=sys.stderr) # 把輸出重定向到一個管道


    2.被重命名或者重新組織的模塊

      1)http

        在Python 3裏,幾個相關的HTTP模塊被組合成一個單獨的包,即http。

             2.x                     3.x

        ①  import httplib          import http.client     # http.client 模塊實現了一個底層的庫,可以用來請求HTTP資源,解析HTTP響應。

        ②  import Cookie           import http.cookies    # http.cookies 模塊提供一個蟒樣的(Pythonic)接口來獲取通過HTTP頭部(HTTP header)Set-Cookie發送的cookies

        ③  import cookielib        import http.cookiejar  # 常用的流行的瀏覽器會把cookies以文件形式存放在磁盤上,http.cookiejar 模塊可以操作這些文件。

        ④  import BaseHTTPServer   import http.server     # http.server 模塊實現了一個基本的HTTP服務器

            import SimpleHTTPServer

            import CGIHttpServer


      2)urllib

        Python 2有一些用來分析,編碼和獲取URL的模塊,但是這些模塊就像老鼠窩一樣相互重疊。在Python 3裏,這些模塊被重構、組合成了一個單獨的包,即urllib。

             2.x                                 3.x

        ①  import urllib                       import urllib.request, urllib.parse, urllib.error

        ②  import urllib2                      import urllib.request, urllib.error

        ③  import urlparse                     import urllib.parse

        ④  import robotparser                  import urllib.robotparser

        ⑤  from urllib import FancyURLopener   from urllib.request import FancyURLopener

            from urllib import urlencode        from urllib.parse import urlencode

        ⑥  from urllib2 import Request         from urllib.request import Request

            from urllib2 import HTTPError       from urllib.error import HTTPError


        以前,Python 2裏的 urllib 模塊有各種各樣的函數,包括用來獲取數據的 urlopen(),還有用來將URL分割成其組成部分的 splittype(), splithost()和 splituser()函數。

        在python3的 urllib 包裏,這些函數被組織得更有邏輯性。2to3將會修改這些函數的調用以適應新的命名方案。

        在Python 3裏,以前的 urllib2 模塊被併入了 urllib 包。同時,以 urllib2 裏各種你最喜愛的東西將會一個不缺地出現在Python 3的 urllib 模塊裏,比如 build_opener()方法, Request 對象, HTTPBasicAuthHandler 和 friends 。

        Python 3裏的 urllib.parse 模塊包含了原來Python 2裏 urlparse 模塊所有的解析函數。

        urllib.robotparse 模塊解析 robots.txt 文件。

        處理HTTP重定向和其他狀態碼的 FancyURLopener 類在Python 3裏的 urllib.request 模塊裏依然有效。 urlencode()函數已經被轉移到了 urllib.parse 裏。

        Request 對象在 urllib.request 裏依然有效,但是像HTTPError這樣的常量已經被轉移到了 urllib.error 裏。


      3)dbm

        所有的DBM克隆(DBM clone)現在在單獨的一個包裏,即dbm。如果你需要其中某個特定的變體,比如GNU DBM,你可以導入dbm包中合適的模塊。

              2.x                3.x

         ①  import dbm         import dbm.ndbm

         ②  import gdbm        import dbm.gnu

         ③  import dbhash      import dbm.bsd

         ④  import dumbdbm     import dbm.dumb

         ⑤  import anydbm      import dbm

             import whichdb


      4)xmlrpc

        XML-RPC是一個通過HTTP協議執行遠程RPC調用的輕重級方法。一些XML-RPC客戶端和XML-RPC服務端的實現庫現在被組合到了獨立的包,即xmlrpc。

              2.x                        3.x

         ①  import xmlrpclib           import xmlrpc.client

         ②  import DocXMLRPCServer     import xmlrpc.server

             import SimpleXMLRPCServer


      5)其他模塊

             2.x                               3.x

        ①  try:                              import io

                import cStringIO as StringIO  # 在Python 2裏,你通常會這樣做,首先嚐試把cStringIO導入作爲StringIO的替代,如果失敗了,再導入StringIO。

            except ImportError:               # 不要在Python 3裏這樣做;io模塊會幫你處理好這件事情。它會找出可用的最快實現方法,然後自動使用它。

                import StringIO

        ②  try:                              import pickle

                import cPickle as pickle      # 在Python 2裏,導入最快的pickle實現也與上邊 io 相似。在Python 3裏,pickle模塊會自動爲你處理,所以不要再這樣做。

            except ImportError:

                import pickle

        ③  import __builtin__                import builtins

        ④  import copy_reg                   import copyreg # copyreg模塊爲用C語言定義的用戶自定義類型添加了pickle模塊的支持。

        ⑤  import Queue                      import queue   # queue模塊實現一個生產者消費者隊列(multi-producer, multi-consumer queue)。

        ⑥  import SocketServer               import socketserver # socketserver模塊爲實現各種socket server提供了通用基礎類。

        ⑦  import ConfigParser               import configparser # configparser模塊用來解析INI-style配置文件。

        ⑧  import repr                       import reprlib # reprlib 模塊重新實現了內置函數 repr(),並添加了對字符串表示被截斷前長度的控制。

        ⑨  import commands                   import subprocess # subprocess 模塊允許你創建子進程,連接到他們的管道,然後獲取他們的返回值。


        builtins模塊包含了在整個Python語言裏都會使用的全局函數,類和常量。重新定義builtins模塊裏的某個函數意味着在每處都重定義了這個全局函數。這聽起來很強大,但是同時也是很可怕的。



註釋

  “#”後面的內容



數據類型

   共4種: 整數、長整數、浮點數和複數。

   1.整數,如:2

   2.長整數,如:22L  # 長整數不過是大一些的整數。Python 3已經取消這種類型,被int取代了。

   3.浮點數,如:3.23 和 52.3E-4  # E標記表示10的冪。在這裏,52.3E-4表示52.3 * 10-4。

   4.複數,如:(-5+4j) 和 (2.3-4.6j)


   在Python 2和Python 3的變化:

   1.八進制(octal)數:

     Python 2: x = 0755   # 0開頭

     Python 3: x = 0o755  # 0o開頭

   2.long 類型

     Python 2有爲非浮點數準備的 int 和 long 類型。 int 類型的最大值不能超過 sys.maxint,而且這個最大值是平臺相關的。

       整數可以通過在數字的末尾附上一個L來定義長整型,顯然,它比 int 類型表示的數字範圍更大。

     Python 3裏,只有一種整數類型 int,大多數情況下,它很像Python 2裏的長整型。

       由於已經不存在兩種類型的整數,所以就沒有必要使用特殊的語法去區別他們。


     由於 long 類型在Python 3的取消,引起以下改變

          Python 2              Python 3            說明

      ① x = 1000000000000L    x = 1000000000000   # 十進制的普通整數

      ② x = 0xFFFFFFFFFFFFL   x = 0xFFFFFFFFFFFF  # 十六進制的普通整數

      ③ long(x)               int(x)              # long()函數沒有了。可以使用int()函數強制轉換一個變量到整型。

      ④ type(x) is long       type(x) is int      # 檢查一個變量是否是整型

      ⑤ isinstance(x, long)   isinstance(x, int)  # 也可以使用 isinstance()函數來檢查數據類型

   3.sys.maxint(sys.maxsize)

     由於長整型和整型被整合在一起了, sys.maxint常量不再精確。

     因爲這個值對於檢測特定平臺的能力還是有用處的,所以它被Python 3保留,並且重命名爲 sys.maxsize。

         Python 2                Python 3

     ① from sys import maxint  from sys import maxsize  # maxint變成了maxsize。

     ② a_function(sys.maxint)  a_function(sys.maxsize)  # 所有的sys.maxint都變成了sys.maxsize。


  int 是 types.IntType 的代名詞

    print(id(int)) # 打印如:505210872

    import types;print(id(types.IntType)) # 打印如:505210872



標識符的命名

    變量是標識符的例子。 標識符 是用來標識 某樣東西 的名字。在命名標識符的時候,你要遵循這些規則:

    1.標識符的第一個字符必須是字母表中的字母(大寫或小寫)或者一個下劃線(‘_’)。

    2.標識符名稱的其他部分可以由字母(大寫或小寫)、下劃線(‘_’)或數字(0-9)組成。

    3.標識符名稱是對大小寫敏感的。例如,myname和myName不是一個標識符。

    有效 標識符名稱的例子有i、__my_name、name_23和a1b2_c3。

    無效 標識符名稱的例子有2things、this is spaced out和my-name。




邏輯行與物理行

  物理行是在編寫程序時文本的一行。邏輯行是程序的一個語句。

  Python假定每個 物理行 對應一個 邏輯行 。 他希望每行都只使用一個語句,這樣使得代碼更加易讀。

  1. 如果你想要在一個物理行中使用多於一個邏輯行,那麼你需要使用分號(;)來特別地標明這種用法。

     分號表示一個邏輯行/語句的結束。

     如: i = 5; print i; # 強烈建議你堅持在每個物理行只寫一句邏輯行。 讓程序見不到分號,而更容易閱讀。

  2. 明確的行連接

     在多個物理行中寫一個邏輯行,行結尾用反斜槓標明

     如: s = 'This is a string. \

         This continues the string.'

         # 上面這兩行是一個邏輯行,打印是: This is a string. This continues the string.

         print \

         i

         # 上面這兩行也是一個邏輯行, 等同於: print i

  3. 暗示的行連接

     在多個物理行中寫一個邏輯行,行結尾不需要使用反斜槓標明。

     這種情況出現在邏輯行中使用了圓括號、方括號或波形括號的時候。

  4. 縮進

     行首的空白是重要的。在邏輯行首的空白(空格和tab符)用來決定邏輯行的縮進層次,從而用來決定語句的分組。

     同一層次的語句必須有相同的縮進。每一組這樣的語句稱爲一個塊。

     不要混合使用tab符和空格來縮進,因爲這在跨越不同的平臺的時候,無法正常工作。強烈建議只使用一種風格來縮進。



語法規則

   1.縮進規則

     一個模塊的界限,完全是由每行的首字符在這一行的位置來決定的(而不是花括號{})。這一點曾經引起過爭議。

     不過不可否認的是,通過強制程序員們縮進,Python確實使得程序更加清晰和美觀。

     在邏輯行首的空白(空格和tab)用來決定邏輯行的縮進層次,從而用來決定語句的分組。錯誤的縮進會引發錯誤。

     注意: 強制縮進的問題,最常見的情況是tab符和空格的混用會導致錯誤,而這是用肉眼無法分別的。

   2.變量沒有類型

     使用變量時只需要給它們賦值。 不需要聲明或定義數據類型。

   3.單語句塊

     如果你的語句塊只包含一句語句,那麼你可以在條件語句或循環語句的同一行指明它。如: if 1!=2: print('Yes')

     強烈建議不要使用這種縮略方法。這會破壞Python清晰美觀的代碼風格,違背設計者的初衷。

     如果是在Python解釋器輸入,它的把提示符會改變爲...以表示語句還沒有結束。這時按回車鍵用來確認語句已經完整了。然後,Python完成整個語句的執行,並且返回原來的提示符來等待下一句輸入。




運算符與表達式:


運算符

   運算符   名稱          說明

     +       加          兩個對象相加,也可以字符串拼接

     -       減          得到負數或是一個數減去另一個數

     *       乘          兩個數相乘 或是返回一個被重複若干次的字符串

     **      冪          返回x的y次冪

     /       除          x除以y

     //      取整除      返回商的整數部分

     %       取模        返回除法的餘數  # 8%3得到2。 -25.5%2.25得到1.5

     <<      左移        把一個數的二進制向左移一定數目 # 2 << 2得到8

     >>      右移        把一個數的二進制向右移一定數目 # 11 >> 1得到5

     &       按位與      數的按位與 # 5 & 3得到1。

     |       按位或      數的按位或 # 5 | 3得到7。

     ^       按位異或    數的按位異或 # 5 ^ 3得到6

     ~       按位翻轉    x的按位翻轉是-(x+1) # ~5得到6。

     <       小於        返回x是否小於y

     >       大於        返回x是否大於y

     <=      小於等於    返回x是否小於等於y

     >=      大於等於    返回x是否大於等於y

     ==      等於        比較對象是否相等

     !=      不等於      比較兩個對象是否不相等(python3刪除了“<>”符號)

     not     布爾“非”  如果x爲True,返回False。如果x爲False,它返回True。 # x = True; not x返回False。

     and     布爾“與”  如果x爲False,x and y返回False,否則它返回y的計算值。 # x=False; y=True; x and y返回False。

     or      布爾“或”  如果x是True,它返回True,否則它返回y的計算值。# x = True; y = False; x or y返回True。

     in, not in          成員測試 (由類裏面的 __contains__ 函數指定返回值)

     is, is not          同性測試 (兩值的 is 運算是判斷引用,與“==”的比較有所不同)



   說明:

     1.加號“+”:有數學相加,也有字符串拼接作用,注意:不能字符串和數字相加。如: 3 + 5得到8; 'a' + 'b'得到'ab'。

     2.乘號“*”:兩個數相乘,也可以把字符串重複拼接若干次,如: 2 * 3得到6; 'la' * 3得到'lalala'。

     3.冪“**” :這種寫法,其他語言好像沒見到過,如: 3 ** 4得到81(即3 * 3 * 3 * 3)

     4.除號“/”:整數的除法得到整數結果,浮點數的得到浮點數,如:4/3得到1(返回相除後結果的向下取整(floor)); 4.0/3或4/3.0得到1.333...

       注意:Python 3.0開始,移除了含糊的除法符號('/'),而只返回浮點數。如:4/3得到1.333...

     5.取整除“//”:將兩數相除,然後對結果取整,如: 7 // 3得到2; 4 // 3.0得到1.0

     6.比較運算符:所有比較運算符返回1表示真,返回0表示假。這分別與特殊的變量 True 和 False 等價。注意大小寫。

       如果兩個操作數都是數字,它們首先被轉換爲一個共同的類型(如double)。否則,它總是返回 False 。

< 3返回0(即False); 而3 < 5返回1(即True)。比較可以被任意連接: 3 < 5 < 7返回True。

       大於、小於、小於等於、大於等於時:數字跟數字可以比較,字符串跟字符串可以比較,但數字不能跟字符串比較。

       等於、不等於時: 數字跟數字可以比較,字符串跟字符串可以比較,數字跟字符串比較返回 False (表示不相等)

       等於: Python 使用“==”來做比較,用“=”來賦值。但不允許內嵌的賦值,所以不會出現你本以爲在做比較而意外的寫成賦值的情況。

     7.布爾運算: and 和 or 都是短路運算,沒有非短路運算的運算符。

       短路運算:當前面一個表達式可以決定結果時,後面的語句不用再判斷。非短路運算時,還照樣判斷後面的。

       注意:在 and or 運算中,空字符串'',數字0,空列表[],空字典{},空元組(), None,在邏輯運算中都被當作假來處理。

     8.and 和 or 的特殊用法:

       由於語言的鬆散性,用 and 和 or 在賦值語句時有判斷作用。

       1) or 用在賦值語句裏,返回第一個邏輯爲真的值, 沒有邏輯爲真的返回最後一個。(如下這寫法比較常用)

          如:ss = False or None or 0 or '' or -1 or 'sss'; print(ss) # 打印:-1 (-1作if判斷時返回 True)

          設定預設值的寫法: edittype = edittype or "text"; # 如果 edittype 之前有值,則取之前的值; 之前爲空,則取默認值

       2) and 用在賦值語句裏,與 or 剛好相反,返回第一個邏輯爲假的值, 沒有邏輯爲假的返回最後一個。

          如: a = 0 and 1; print(a) # 打印: 0

          a = 2 and 1; print(a) # 打印: 1

          應用: valid = True; valid = valid and checkLength(name, 16); valid = valid and checkLength(name, 16); # 如果前面的驗證不通過,則後面的不再驗證

       簡便的記憶是: and 偏 False, or 偏 True

       要理解 and 和 or 的這種寫法,得考慮到它的短路運算特性。它是在做邏輯判斷,但返回的是前或後一個的值,而不是返回 True 或 False 。

     9.三目運算符:

       Python 沒有三目運算符“cond ? a : b”,但可以使用 and 和 or 來代替(需理解前面的 and 和 or 的特殊用法),如下:

       1) c = cond and a or b   # 這多數情況下是正確的,但當 a 是空字符串''、數字0等邏輯運算爲假的情況下會出錯。

       2) c = (cond and [a] or [b])[0] # 即使 a或者b爲一個邏輯假的值,將他放入集合中後,就爲真了,也就是[False] [None]都不爲假。

       3) c = (b, a)[cond and 1 or 0] # 注意 a和b的位置是顛倒的,將表達式結果轉成1和0來作爲元組下標而選擇結果。

       4) c = a if cond else b # 使用 if else 寫條件(python特有的寫法,建議使用,前3種寫法難理解也容易出錯)

     10.自增,自減:

       Python 沒有“++”和“--”兩個語法,自增自減時只能寫: i = i + 1 或者 i += 1, 不能用 i++

       這在一定程度上避免出錯,因爲新手經常搞錯“++”放前面還是放後面; 但這也導致 for 循環的寫法與其它語言很不同

     11.switch/case 語句

        Python現在不支持這語句,但可以用 range(N) 生成一個 列表

     12.一次性的多比較

        “ if (0 < n < 4000) ”這種寫法在python是允許的,它等價於“ if ((0 < n) and (n < 4000)) ”但前者更適合閱讀。



運算符優先級

    下面這個表給出Python的運算符優先級,從最低的優先級(最鬆散地結合)到最高的優先級(最緊密地結合)。

    在一個表達式中,Python會首先計算下表中較下面的運算符,然後在計算列在下表上部的運算符。

    在下表中列在同一行的運算符具有 相同優先級 。例如,+和-有相同的優先級。

    建議使用圓括號來分組運算符和操作數,以便能夠明確地指出運算的先後順序,使程序儘可能地易讀。例如,2 + (3 * 4)顯然比2 + 3 * 4清晰。


    運算符                   描述

    lambda                  Lambda表達式

    or                      布爾“或”

    and                     布爾“與”

    not x                   布爾“非”

    in,not in              成員測試

    is,is not              同一性測試

    <,<=,>,>=,!=,==    比較

    |                       按位或

    ^                       按位異或

    &                       按位與

    <<,>>                  移位

    +,-                    加法與減法

    *,/,%                 乘法、除法與取餘

    +x,-x                  正負號

    ~x                      按位翻轉

    **                      指數

    x.attribute             屬性參考

    x[index]                下標

    x[index:index]          尋址段

    f(arguments...)         函數調用

    (experession,...)       綁定或元組顯示

    [expression,...]        列表顯示

    {key:datum,...}         字典顯示

    'expression,...'        字符串轉換



計算順序

    默認地,運算符優先級表決定了哪個運算符在別的運算符之前計算。然而,如果要改變它們的計算順序,得使用圓括號。

    例如,你想要在一個表達式中讓加法在乘法之前計算,那麼你就得寫成類似(2 + 3) * 4的樣子。



結合規律

    運算符通常由左向右結合,即具有相同優先級的運算符按照從左向右的順序計算。例如,2 + 3 + 4被計算成(2 + 3) + 4。

    一些如賦值運算符那樣的運算符是由右向左結合的,即a = b + c被處理爲a = (b + c)。


對象

    Python 將 "一切皆對象" 貫徹得非常徹底,不區分什麼 "值類型" 和 "引用類型"。所謂變量,實質就是一個通用類型指針 (PyObject*),它僅僅負責指路,至於目標是誰,一概不管。

    Python Object 對象的自身結構了。任何對象,就算一個最簡單的整數,它的頭部都會擁有 2 個特殊的附加信息,分別是:"引用計數" 和 "類型 (type) 指針" 。前者指示 GC 何時回收,而後者標明瞭對象的身份,如此我們就可以在運行期動態執行對象成員調用。


    連同附加頭,一個 "普通" 的整數起碼得 12 字節:

    a = 8; import sys; print(sys.getsizeof(a)) # 打印: 12  (python3.2中,打印的是14)

    print(sys.getsizeof(None)) # 打印: 8



字符串

   1.使用單引號“'”引起來: 'Quote me on this'

   2.使用雙引號“"”引起來: "What's your name?"

   3.使用三引號('''或"""): 可以指示一個多行的字符串。你可以在三引號中自由的使用單引號和雙引號。 /'''

     如:

     """This is a multi-line string. This is the first line.

     "What's your name?," I asked.

     He said "Bond, James Bond."

     """

   4.轉義符“\”

     \\  指示反斜槓本身

     \'  指示單引號

     \"  指示雙引號

     注意: 行末的單獨一個反斜槓表示字符串在下一行繼續,而不是開始一個新的行。

   5.自然字符串

     自然字符串通過給字符串加上前綴r或R來指定,取消轉義符的功能。例如: r"Newlines are indicated by \n"。

     三引號的字符串也可以同樣用法,如:R'''Newlines are indicated by \n'''

   6.Unicode字符串

     Python允許你處理Unicode文本(超過拉丁文字範圍的)——只需要在字符串前加上前綴u或U。

     例如,u"This is a Unicode string.哈哈.."。(Python3.x之後不需要這樣了,可以直接寫中文;而這樣寫會報錯)

     Python 3.0開始對unicode全面支持,所有的文本(str)都是Unicode的;並引入了一個叫做bytes的新類型來處理字節序列。而編碼過的Unicode會以二進制的數據來表示。

     因爲在2.x的世界裏,大量的bug都是因爲已編碼的文本和未編碼的文本混雜在一起而產生的。

   7.按字面意義級連字符串

     如果你把兩個字符串按字面意義相鄰放着,他們會被Python自動級連。

     例如,"What's" ' your name?'會被自動轉爲"What's your name?"。

     即是說,兩個字符串放在一起,會有字符拼接的效果。加號“+”也有字符拼接的效果。

   8.字符串拼接

     可以使用“str1.__add__(str2)”或者“str1 + str2”或者直接兩個字符串放一起,來拼接字符串

     但字符串與其它類型拼接時,得先把其它類型轉成字符串類型,否則會出錯。如“str1 + 2”就會出錯,需要“str1 + str(2)”

   9.格式化

     使用“%控制符”可以格式化字符串,非常方便。如: str1 = "Swaroop's age is %d, weight is %f" % (5, 65.5)

     “%(name)控制符”可按名稱傳參數(不寫名稱是按位置傳參數),如: str = "%(row)d Rows is %(value)s" % { 'value': 'kkkk', 'row': 22 }

     格式化的符號用法參考下面的“字符串格式化控制表”

     另外,string.format()函數也可以格式化字符串

     例如:'subtracting {0}, adding {1}'.format(1, 'haha') # 參數講對應到“{number}”的位置上

   10.字符串序列(索引和切片)

     字符串可以使用下標來獲取字符串中某個項目,以及截取字符串。詳情參考“序列”

     用法如: name = 'swaroop'; name[1]; name[1:3]; name[1:-1]

   11.str(anything)函數和 unicode(anything)函數

     Python 2有兩個全局函數可以把對象強制轉換成字符串:unicode()把對象轉換成Unicode字符串,還有 str()把對象轉換爲非Unicode字符串。

     Python 3只有一種字符串類型,Unicode字符串,所以 str()函數即可完成所有的功能。(unicode()函數在Python 3裏不再存在了。)

   另外:

     沒有專門的char數據類型,確實沒有需要有這個類型。

     單引號和雙引號字符串是完全相同的——它們沒有在任何方面有不同。

     正則表達式: 一定要用自然字符串處理正則表達式。否則會需要使用很多的反斜槓。

     使用 help(str) 可查看字符串對象定義的所有方法及屬性。

     由於百分號有特殊作用,所以字符串裏面要用百分號的話需要使用“%%”,如:"select * from my_table where name like '%%測試%%'"



字符串格式化控制:(未參考幫助文檔,只是個人猜測)

   轉義符 (Escape Sequence):

   \ddd     1到3位8進制數指定Unicode字符輸出(如:“\127”顯示“W”)

   \uxxxx   1到4位16進制數指定Unicode字符輸出(Python3.x開始支持此寫法,如: \u54C8 顯示“哈”字)

   \xhh     16進制數指定Unicode字符輸出(如:“\xe5\x93\x88”顯示“哈”)

   \\       \

   \        \ (單獨的一個斜槓也顯示斜槓,即不後接有轉移作用的字符時,作爲斜槓使用)

   \'       '

   \"       "

   \a       字符:0x07    響鈴(ASCII控制字符)

   \b       字符:0x08    退格(光標向左走一格)(ASCII控制字符)

   \f       字符:0x0c    Formfeed(FF)(走紙轉頁,換頁)(ASCII控制字符)

   \n       字符:0x0a    換行(ASCII控制字符)

   \N{name} Unicode字符   只能針對Unicode

   \r       字符:0x0d    回車

   \t       字符:0x09    跳格(tab符號),水平製表符

   \v       字符:0x0b    垂直製表符


   %%       %

   %d       輸出10進制整數,只能是數字類型,輸出字符串類型會出錯;浮點類型的數字將被取整(直接刪除小數部分)。

   %f,%F    以10進制輸出浮點數,只能是數字類型,輸出字符串類型會出錯。

   %e,%E    以科學計數法輸出10進制的浮點數,大小寫的“e”反應在顯示時科學計數法的“e/E”上,只能是數字類型。

   %a       Python3.0開始支持此寫法,原樣輸出結果,字符串類型會加上單引號引起來。

   %o       (字母o)以8進制整數方式輸出,只能是數字類型;浮點類型的數字將被取整(直接刪除小數部分)。

   %x,%X    將數字以16進制方式輸出,只能是數字類型;浮點類型的數字將被取整(直接刪除小數部分)。

   %s       將字符串格式化輸出(可輸出任何類型)

   %c       以字符方式輸出,提供的類型必須是 char 或 int 。

   注:布爾類型的 True 或 False,用數字類型輸出是 1或0,字符串輸出是 True 或 False。


   字符串轉換成數字

    float(str)     轉換成浮點數,如, float("1e-1") 結果:0.1

    int(str)       轉換成整數,如, int("12") 結果:12

    int(str,base)  轉換成base進制的整數,如, int("11",2) 轉換成2進制的整數,結果:3

    long(str)      轉換成長整數,Python3取消此語法,如, long("12L") 結果:12L

    long(str,base) 轉換成base進制的長整數,Python3取消此語法,如, long("11L",2) 結果:3L


字符串用例

    name = 'Swaroop' # This is a string object


    # 檢查字符串的開頭部分

    if name.startswith('Swa'):  # 類似函數如 endswith()

        print('Yes, the string starts with "Swa"')


    # 檢查是否包含有此內容

    if 'a' in name:

        print('Yes, it contains the string "a"')


    # 找出給定字符串的位置,找不到則返回-1

    if name.find('war') != -1:

        print('Yes, it contains the string "war"', 's')


    # join()函數把列表拼接起來

    delimiter = '; '

    mylist = ['Brazil', 'Russia', 'India', 'China']

    print(delimiter.join(mylist)) # 打印: Brazil; Russia; India; China


    # 大小寫轉換

    print("THIS IS TEST".lower())    # 轉換成小寫,打印:this is test

    print("this is test".upper())    # 轉換成大寫,打印:THIS IS TEST

    print("This Is Test".swapcase()) # 大小寫互換,打印:tHIS iS tEST


    print("  This Is Test  ".strip()) # 去掉前後空格,打印:This Is Test


    # 常用 string 函數

    replace(string,old,new[,maxsplit])

        字符串的替換函數,把字符串中的old替換成new。默認是把string中所有的old值替換成new值,如果給出maxsplit值,還可控制替換的個數,如果maxsplit爲1,則只替換第一個old值。

        如: a="11223344";print(string.replace(a,"1","one")) # 打印: oneone2223344

             print(string.replace(a,"1","one",1)) # 打印: one12223344

        b = "dfsdf   dfsdfsd dfsdf  ";print(a.replace(' ', '')) # 打印: dfsdfdfsdfsddfsdf


    capitalize(string)

        該函數可把字符串的首個字符替換成大字。

    如: import string; print(string.capitalize("python")) # 打印: Python


    split(string,sep=None,maxsplit=-1)

        從string字符串中返回一個列表,以sep的值爲分界符。

    如: import string; ip="192.168.3.3"; print(string.split(ip,'.')) # 打印: ['192', '168', '3', '3']



控制檯輸入

    使用 raw_input()函數 或者 input()函數 能夠很方便的控從制臺讀入數據,得到的是字符串。

    Python2.x時,raw_input()和 input()的區別:

        當輸入爲純數字時:input()返回的是數值類型,如:int,float; raw_input()返回的是字符串類型

        input()會計算在字符串中的數字表達式,而 raw_input()不會。如輸入“57+3”: input()得到整數60,raw_input()得到字符串'57+3'

    注:Python3.0將 raw_input()函數去除了,而用 input() 取代它的功能。另外,input()獲取的字符串會包括結尾的換行符。

    例:(此處是Python2.6的寫法,3.x時應該把 raw_input() 改成 input())

      1.輸入字符串

        nID = raw_input("Input your id plz:\n"); print('your id is %s' % (nID))

      2.輸入整數

        nAge = int(raw_input("input your age plz:\n")); print('your age is %d\n' % nAge)

      3.輸入浮點型

        fWeight = float(raw_input("input your weight:\n")); print('your weight is %f' % fWeight)

      4.輸入16進制數據

        nHex = int(raw_input('input hex value(like 0x20):\n'),16); print('nHex = %x,nOct = %d\n' %(nHex,nHex))

      5.輸入8進制數據

        nOct = int(raw_input('input oct value(like 020):\n'),8); print('nOct = %o,nDec = %d\n' % (nOct,nOct))

    注:打印字符串時,“%”作爲特殊符號,兩個百分號才能打印出一個百分號


    Python 2 與 Python 3 的比較

       Python 2             Python 3

    ① raw_input()          input()          # 最簡單的形式,raw_input()被替換成input()。

    ② raw_input('prompt')  input('prompt')  # 可以指定一個提示符作爲參數

    ③ input()              eval(input())    # 如果想要請求用戶輸入一個Python表達式,計算結果




控制流:


if 語句

    寫法: if ... elif ... else ...  # if後面不用圓括號

    注:在Python中沒有switch語句。你可以使用 if..elif..else 語句來完成同樣的工作(在某些場合,使用字典會更加快捷。)

    在C/C++裏面可以使用 else if ,但這裏不行,得寫成: else :\n\t if,故此增加關鍵字 elif


    例:

    number = 23

    # int是一個類,不過這裏它只是把一個字符串轉換爲一個整數(假設這個字符串含有一個有效的整數文本信息)。

    guess = int(raw_input('Enter an integer : '))


    if guess == number:

        print('Congratulations, you guessed it.')

    elif guess < number:

        print('No, it is a little higher than that') # Another block

    else:

        print('No, it is a little lower than that')



while 語句

    只要條件爲真,while語句允許你重複執行一塊語句。

    注:while語句有一個可選的else從句。else塊事實上是多餘的,因爲可以把其中的語句跟在while語句裏面。


    例:

    number = 23

    running = True


    while running:

        guess = int(raw_input('Enter an integer : '))


        if guess == number:

            print('Congratulations, you guessed it.')

            running = False # this causes the while loop to stop

        elif guess < number:

            print('No, it is a little higher than that')

        else:

            print('No, it is a little lower than that')

    else:

        # Do anything else you want to do here

        print('The while loop is over.')



for 循環

    for..in 是另外一個循環語句,它在一序列的對象上 遞歸 即逐一使用隊列中的每個項目。

    else 部分是可選的。如果包含 else,它總是在 for 循環結束後執行一次,除非遇到 break 語句。


    例:

    for i in range(1, 5):

        print(i)

    else:

        print('The for loop is over')


    # 打印結果: 1 至 4 以及 else 的內容

    # range(1,5)給出序列[1, 2, 3, 4]。range默認步長爲1,第三個參數是步長。如,range(1,5,2)給出[1,3]。

    # 記住,range包含第一個數,但不包含第二個數。


    注:

    Python的 for 循環從根本上不同於C/C++的 for 循環。類似 foreach 循環。

    在C/C++中,如果你想要寫 for (int i = 0; i < 5; i++),那麼用Python,你寫成 for i in range(0,5)。


    # 範例:九九乘法表

    # 由於Python2 與Python3的 print 語法不相同,改用string來打印,保證兩個版本的輸出結果相同。

    str = ''

    for i in range(1,10):

        for j in range(1, i+1):

            str += ('%d * %d = %d \t' % (j, i, i*j))

        str += '\n'

    print(str)



break 語句

    break 語句是用來 終止 循環語句的,即哪怕循環條件沒有稱爲 False 或序列還沒有被完全遞歸,也停止執行循環語句。

    一個重要的註釋是,如果你從 for 或 while 循環中 終止 ,任何對應的循環 else 塊將不執行。


continue 語句

    continue 語句被用來告訴Python跳過當前循環塊中的剩餘語句,然後 繼續 進行下一輪循環。

    break 語句 和 continue 語句 對於 while 循環 和 for 循環 都有效。


    例(2.x寫法):

    while True:

        s = raw_input('Enter something : ')

        if s == 'quit':

            break

        if len(s) < 3:

            print 'Input is not of sufficient length'

            continue

        # Do other kinds of processing here...

        print 'Length of the string is', len(s)


    例(3.x寫法):

    while True:

        s = input('Enter something : ')  # 3.x用input()代替raw_input(),且會獲取結尾輸入的換行符

        s = s[:-1] # 去掉結尾的換行符

        if s == 'quit':

            break

        if len(s) < 3:

            print('Input is not of sufficient length')

            continue

        # Do other kinds of processing here...

        print('Length of the string is', len(s))



函數:


定義函數

    函數通過def關鍵字定義。

    def關鍵字後跟一個函數的 標識符 名稱,然後跟一對圓括號。圓括號之中可以包括一些變量名,該行以冒號結尾。

    接下來是一塊語句,它們是函數體。


    例:

    def sayHello():

        print('Hello World!') # block belonging to the function


    sayHello() # call the function



函數形參

    函數中的參數名稱爲 形參 而你提供給函數調用的值稱爲 實參 。


局部變量

    當你在函數定義內聲明變量的時候,它們與函數外具有相同名稱的其他變量沒有任何關係,即變量名稱對於函數來說是 局部 的。

    這稱爲變量的 作用域 。所有變量的作用域是它們被定義的塊,從它們的名稱被定義的那點開始。


    例:

    x = 50

    def func(x):

        print('x is', x)

        x = 2

        print('Changed local x to', x) # 打印: 2

    func(x)

    print('x is still', x) # 打印: 50, 值沒有變



global 語句

    如果要爲一個定義在函數外的變量賦值,那麼你就得告訴Python這個變量名不是局部的,而是 全局 的。使用global語句完成這一功能。

    沒有global語句,是不可能爲定義在函數外的變量賦值的。

    你可以使用定義在函數外的變量的值(假設在函數內沒有同名的變量)。然而,應避免這樣做,因爲這降低程序的可讀性,不清楚變量在哪裏定義的。

    使用global語句可以清楚地表明變量是在外面的塊定義的。

    注:可以使用同一個global語句指定多個全局變量。例如 global x, y, z。


    例:

    def func():

        global x

        print('x is', x)

        x = 2

        print('Changed local x to', x)  # 打印: 2


    x = 50

    func()

    print('Value of x is', x)  # 打印: 2, 值被改變了



默認參數值

    如果希望一些參數是 可選 的,這些參數可使用默認值。

    可以在函數定義的形參名後加上賦值運算符(=)和默認值,從而給形參指定默認參數值。

    注意,默認參數值應該是一個參數。


    例:

    def say(message, times = 2):

        print(message * times)


    say('Hello ')     # 打印:Hello Hello

    say('World ', 5)  # 打印:World World World World World


    重要:

    只有在形參表末尾的那些參數可以有默認參數值,即不能在聲明函數形參的時候,先聲明有默認值的形參而後聲明沒有默認值的形參。

    這是因爲賦給形參的值是根據位置而賦值的。例如,def func(a, b=5)是有效的,但是def func(a=5, b)是 無效 的。



關鍵參數

    如果某個函數有許多參數,而你只想指定其中的一部分,那麼可以通過命名來爲這些參數賦值

    ——這被稱作 關鍵參數 ——使用名字(關鍵字)而不是位置來給函數指定實參。

    這樣做有兩個優勢:

      一、由於我們不必擔心參數的順序,使用函數變得更加簡單了。

      二、假設其他參數都有默認值,我們可以只給我們想要的那些參數賦值。


    例:

    def func(a, b=5, c=10):

        print('a is', a, 'and b is', b, 'and c is', c)


    func(3, 7)        # 參數a得到值3,參數b得到值7,而參數c使用默認值10。

    func(25, c=24)    # 根據實參的位置,變量a得到值25。根據命名,即關鍵參數,參數c得到值24。變量b根據默認值,爲5。

    func(c=50, a=100) # 使用關鍵參數來完全指定參數值。a得到值100,c得到值50。變量b根據默認值,爲5。



return 語句

    return語句用來從一個函數 返回 即跳出函數。我們也可選從函數 返回一個值 。


    例:

    def maximum(x, y):

        if x > y:

            return x

        else:

            return y


    print(maximum(2, 3)) # 打印 3



None

    None 是Python中表示沒有任何東西的特殊類型(相當於java的 null)。例如,如果一個變量的值爲None,可以表示它沒有值。

    注意:函數沒有返回值的,等價於最後返回return None。通過運行print someFunction(),你可以明白這一點。


    例:

    def someFunction():

        # pass語句在Python中表示一個空的語句塊。它後面的代碼會照常運行。

        pass


    print(someFunction())



DocStrings

    DocStrings:文檔字符串。它是一個重要的工具,幫助你的程序文檔更加簡單易懂,應該儘量使用它。甚至可以在程序運行的時候,從函數恢復文檔字符串!

    在函數的第一個邏輯行的字符串是這個函數的 文檔字符串 。注意,DocStrings也適用於模塊和類。

    文檔字符串的慣例是一個多行字符串,它的首行以大寫字母開始,句號結尾。第二行是空行,從第三行開始是詳細的描述。 強烈建議遵循這個慣例。


    例:

    def printMax(x, y):

        '''Prints the maximum of two numbers.


        The two values must be integers.'''


        x = int(x) # convert to integers, if possible

        y = int(y)

        if x > y:

            print(x, 'is maximum')

        else:

            print(y, 'is maximum')


    printMax(3, 5)  # 打印: 5 is maximum

    print(printMax.__doc__)   # 打印: Prints the maximum ... must be integers.


    注:

    使用__doc__(注意是兩個下劃線)調用printMax函數的文檔字符串屬性。請記住Python把 每一樣東西 都作爲對象,包括這個函數。

    Python中help()函數即是使用DocStings的了,它只是抓取函數的__doc__屬性,然後整潔地展示給你。可以對上面的函數嘗試一下: help(printMax)。記住按q退出help。

    自動化工具也可以以同樣的方式從你的程序中提取文檔。因此強烈建議你對你所寫的任何正式函數編寫文檔字符串。



函數屬性 func_*

    在Python 2裏,函數的裏的代碼可以訪問到函數本身的特殊屬性。在Python 3裏,爲了一致性,這些特殊屬性被重新命名了。


    Python 2 與 Python 3 的比較

          Python 2                  Python 3                說明

      ① a_function.func_name      a_function.__name__     # 包含了函數的名字。

      ② a_function.func_doc       a_function.__doc__      # 包含了在函數源代碼裏定義的文檔字符串(docstring)。

      ③ a_function.func_defaults  a_function.__defaults__ # 是一個保存參數默認值的元組。

      ④ a_function.func_dict      a_function.__dict__     # 一個支持任意函數屬性的名字空間。

      ⑤ a_function.func_closure   a_function.__closure__  # 一個由cell對象組成的元組,包含了函數對自由變量(free variable)的綁定。

      ⑥ a_function.func_globals   a_function.__globals__  # 一個對模塊全局名字空間的引用,函數本身在這個名字空間裏被定義。

      ⑦ a_function.func_code      a_function.__code__     # 一個代碼對象,表示編譯後的函數體。




模塊:

    如果要在其他程序中重用很多函數,那麼你該使用模塊。

    模塊基本上就是一個包含了所有你定義的函數和變量的文件。

    爲了在其他程序中重用模塊,模塊的文件名必須以.py爲擴展名。


sys模塊(標準庫模塊)

    sys模塊包含了與Python解釋器和它的環境有關的函數。


    例:

    import sys  # 輸入 sys模塊。基本上,這句語句告訴Python,我們想要使用這個模塊。

    print('The command line arguments are:')

    # 打印調用文件的命令行參數

    for i in sys.argv:

        print(i)


    print('\nThe PYTHONPATH is', sys.path)


    輸出:

    $ python using_sys.py we are arguments

    The command line arguments are:

    using_sys.py

    we

    are

    arguments


    The PYTHONPATH is ['/home/swaroop/byte/code', '/usr/lib/python23.zip',

    '/usr/lib/python2.3', '/usr/lib/python2.3/plat-linux2',

    '/usr/lib/python2.3/lib-tk', '/usr/lib/python2.3/lib-dynload',

    '/usr/lib/python2.3/site-packages', '/usr/lib/python2.3/site-packages/gtk-2.0']


    注:

    執行 import sys 語句的時候,它在 sys.path 變量中所列目錄中尋找 sys.py 模塊。

    如果找到了這個文件,這個模塊的主塊中的語句將被運行,然後這個模塊將能夠被你使用。

    注意,初始化過程僅在我們 第一次 輸入模塊的時候進行。另外,“sys”是“system”的縮寫。

    腳本的名稱總是sys.argv列表的第一個參數。所以,在這裏,'using_sys.py'是sys.argv[0]、'we'是sys.argv[1]。


    sys.path包含輸入模塊的目錄名列表。

    可以觀察到sys.path的第一個字符串是空的——這個空的字符串表示當前目錄也是sys.path的一部分,這與PYTHONPATH環境變量是相同的。

    這意味着你可以直接輸入位於當前目錄的模塊。否則,你得把你的模塊放在sys.path所列的目錄之一。


    另外:

    sys.exit() # 程序結束

    sys.stdin、 sys.stdout 和 sys.stderr 分別對應你的程序的標準輸入、標準輸出和標準錯誤流。



字節編譯的.pyc文件

    輸入一個模塊相對來說是一個比較費時的事情,所以Python做了一些技巧,以便使輸入模塊更加快一些。

    一種方法是創建 字節編譯的文件,這些文件以.pyc作爲擴展名。另外,這些字節編譯的文件也是與平臺無關的。

    當你在下次從別的程序輸入這個模塊的時候,.pyc文件是十分有用的——它會快得多,因爲一部分輸入模塊所需的處理已經完成了。



from ... import 語句

    如果你想要直接輸入 argv 變量到你的程序中(避免在每次使用它時打sys.),那麼你可以使用 from sys import argv 語句。

    如果你想要輸入所有 sys 模塊使用的名字,那麼你可以使用 from sys import *語句。

    這對於所有模塊都適用。

    注意:

        1.使用 from package import item 方式導入包時,這個子項(item)既可以是包中的一個子模塊(或一個子包),也可以是包中定義的其它命名,像函數、類或變量。

          import 語句首先覈對是否包中有這個子項,如果沒有,它假定這是一個模塊,並嘗試加載它。如果沒有找到它,會引發一個 ImportError 異常。

        2.使用像 import item.subitem.subsubitem 這樣的語句時,這些子項必須是包,最後的子項可以是包或模塊,但不能是前面子項中定義的類、函數或變量。

        3.應該避免使用 from...import 而使用 import 語句,因爲這樣可以使你的程序更加易讀,也可以避免名稱的衝突。



import ... as

    爲 import 的模塊起一個簡稱。如: import cPickle as p

    起簡稱後,下面的語句即可使用簡稱,如原本的 cPickle.dump() 可寫成 p.dump()


模塊的 __name__

    每個模塊都有一個名稱,在模塊中可以通過語句來找出模塊的名稱。

    這在一個場合特別有用——就如前面所提到的,當一個模塊被第一次輸入的時候,這個模塊的主塊將被運行。

    假如我們只想在程序本身被使用的時候運行主塊,而在它被別的模塊輸入的時候不運行主塊,我們該怎麼做呢?這可以通過模塊的__name__屬性完成。

    每個Python模塊都有它的__name__,如果它是'__main__',這說明這個模塊被用戶單獨運行,我們可以進行相應的恰當操作。


    例:

    # Filename: using_name.py

    if __name__ == '__main__':

        print('This program is being run by itself')

    else:

        print('I am being imported from another module')


    輸出:

    $ python using_name.py

    This program is being run by itself


    $ python

    >>> import using_name

    I am being imported from another module



自定義模塊

    每個Python程序也是一個模塊。


    模塊,例:

    # Filename: mymodule.py


    def sayhi():

        print('Hi, this is mymodule speaking.')


    version = '0.1'


    # End of mymodule.py


   上面是一個 模塊 的例子。你已經看到,它與我們普通的Python程序相比並沒有什麼特別之處。

   記住這個模塊應該被放置在我們輸入它的程序的同一個目錄中,或者在 sys.path 所列目錄之一。


    用例1:

    import mymodule

    mymodule.sayhi()

    print('Version', mymodule.version)


    注:函數和成員都以點號來使用。


    用例2:  使用from..import語法的版本。

    from mymodule import sayhi, version  # 或者寫: from mymodule import *


    sayhi()

    print('Version', version)



包(Packages)

    包通常是使用用“圓點模塊名”的結構化模塊命名空間。例如, A.B 表示名爲"A" 的包中含有名爲"B"的子模塊。

    使用圓點模塊名保存不同類庫的包可以避免模塊之間的命名衝突。(如同用模塊來保存不同的模塊架構可以避免變量之間的命名衝突)

    包目錄必須要有一個 __init__.py 文件的存在;這是爲了防止命名衝突而無意中在隨後的模塊搜索路徑中覆蓋了正確的模塊。

    最簡單的情況下, __init__.py 可以只是一個空文件,不過它也可能包含了包的初始化代碼,或者設置了 __all__ 變量。



dir()函數

    使用內建的dir函數來列出模塊定義的標識符。標識符有函數、類和變量。

    當你爲 dir()提供一個模塊名的時候,它返回模塊定義的名稱列表。如果不提供參數,它返回當前模塊中定義的名稱列表。


    $ python

    >>> import sys

    >>> dir(sys) # get list of attributes for sys module

    ['__displayhook__', '__doc__', '__excepthook__', '__name__', '__stderr__',

    '__stdin__', '__stdout__', '_getframe', 'api_version', 'argv',

    'builtin_module_names', 'byteorder', 'call_tracing', 'callstats',

    'copyright', 'displayhook', 'exc_clear', 'exc_info', 'exc_type',

    'excepthook', 'exec_prefix', 'executable', 'exit', 'getcheckinterval',

    'getdefaultencoding', 'getdlopenflags', 'getfilesystemencoding',

    'getrecursionlimit', 'getrefcount', 'hexversion', 'maxint', 'maxunicode',

    'meta_path','modules', 'path', 'path_hooks', 'path_importer_cache',

    'platform', 'prefix', 'ps1', 'ps2', 'setcheckinterval', 'setdlopenflags',

    'setprofile', 'setrecursionlimit', 'settrace', 'stderr', 'stdin', 'stdout',

    'version', 'version_info', 'warnoptions']

    >>> dir() # get list of attributes for current module

    ['__builtins__', '__doc__', '__name__', 'sys']

    >>>

    >>> a = 5 # create a new variable 'a'

    >>> dir()

    ['__builtins__', '__doc__', '__name__', 'a', 'sys']

    >>>

    >>> del a # delete/remove a name; 這個得留意

    >>>

    >>> dir()

    ['__builtins__', '__doc__', '__name__', 'sys']

    >>>



數據結構

    可以處理一些 數據 的 結構 。或者說,它們是用來存儲一組相關數據的。

    在Python中有三種內建的數據結構——列表、元組和字典。


列表(list, 有的語言稱爲:數組)

    是處理一組有序項目的數據結構,即你可以在一個列表中存儲一個 序列 的項目。

    列表中的項目應該包括在方括號中,每個項目之間用逗號分割。

    可以添加、刪除或是搜索列表中的項目。列表是 可變的 數據類型。

    列表對象定義的所有方法可以通過 help(list) 獲得完整的知識。我比較習慣稱它爲“數組”。


    例:

    shoplist = ['apple', 'mango', 'carrot', 'banana']

    #查看長度

    print('I have', len(shoplist),'items to purchase.')

    #遍歷

    print('These items are:', end=' ') # 注意這行的結尾,打印時可以不換行,python 2.x應該用逗號結尾

    for item in shoplist:

        print(item, end=' ') # python 2.x 此行應該寫:“print item,”


    #添加

    print('\nI also have to buy rice.')

    shoplist.append('rice')

    print('My shopping list is now:', shoplist)


    #排序

    print('I will sort my list now')

    shoplist.sort()

    print('Sorted shopping list is:', shoplist)


    #刪除,以及使用下標

    print('The first item I will buy is:', shoplist[0])

    olditem = shoplist[0]

    del shoplist[0]

    print('I bought the', olditem)

    print('My shopping list is now:', shoplist)


    #多維列表時,保存的對象只是引用

    newlist = ['waa','dd']

    shoplist.append(newlist)

    print('My shopping list is now:', shoplist)

    del newlist[0]

    print('My shopping list is now', shoplist)


    # 刪除重複, 用 set (對元組也可以這樣寫)

    L = [1,1,1,2,2]

    print(list(set(L))) # 打印:[1, 2]

    l = [(1, 2), (1, 2), 3, 5, 4, 3, 4, (1, 2), 0, 5]

    l = list(set(l))

    print(l) # 打印: [(1, 2), 0, 3, 4, 5]


    # 複製列表(淺拷貝)

    c = shoplist[:]

    # 複製(深拷貝)

    import copy

    c = copy.deepcopy(shoplist)



元組(tuple)

    元組和列表十分類似,只不過元組和字符串一樣是 不可變的 即你不能修改元組。

    元組通過圓括號中用逗號分割的項目定義。

    元組通常用在使語句或用戶定義的函數能夠安全地採用一組值的時候,即被使用的元組的值不會改變。

    如果你想要知道元組對象定義的所有方法,可以通過 help(tuple) 獲得完整的知識。


    例:

    #一維元組

    zoo = ('wolf', 'elephant', 'penguin')

    print('Number of animals in the zoo is %s' % len(zoo))  # 打印: 3


    newlist = ['waa','dd']

    #多維元組

    new_zoo = ('monkey', 'dolphin', zoo, newlist)

    print('Number of animals in the new zoo is %s' % len(new_zoo))  # 打印: 3

    print('All animals in new zoo are %s' % str(new_zoo))  # 打印: ('monkey','dolphin',('wolf','elephant','penguin'),['waa','dd'])

    print('Animals brought from old zoo are %s' % str(new_zoo[2]))  # 打印: ('wolf', 'elephant', 'penguin')

    print('Last animal brought from old zoo is %s' % new_zoo[2][2]) # 打印: penguin


    #多維元組時,保存的對象只是引用

    del newlist[0]

    print('new_zoo is now:' + str(new_zoo) )  # 打印: ('monkey','dolphin',('wolf','elephant','penguin'),['dd'])


    注意:含有0個或1個項目的元組

    一個空的元組(含有0個項目)由一對空的圓括號組成,如myempty = ()。

    含有單個元素的元組必須在第一個(唯一一個)項目後跟一個逗號。如: singleton = (2 , )。

    如果小括號裏面只有唯一一個項目,而這個項目後面又沒有跟一個逗號的話,Python會認爲它是一個表達式。



字典(dict, 有的語言稱爲:json)

    字典把鍵(名字)和值(詳細情況)聯繫在一起。

    注意,鍵必須是唯一的,且只能使用不可變的對象(比如字符串)來作爲字典的鍵,但字典的值沒有此限制。應該說只能使用簡單的對象作爲鍵。

    鍵值對在字典中以這樣的方式標記:d = {key1 : value1, key2 : value2 }。

    鍵值對用冒號分割,而各個對用逗號分割,所有這些都包括在花括號中。

    記住字典中的鍵/值對是沒有順序的。如果要一個特定的順序,那麼應該在使用前自己對它們排序。

    字典是dict類的實例/對象,可以用 help(dict) 來查看其屬性和函數。


    例:

    ab = { 'Swaroop': 'swar',

           'Larry'  : 'larry',

           'Spammer': 'spammer'

         }

    print(ab) # 打印: {'Swaroop':'swar', 'Larry':'larry', 'Spammer':'spammer'}

    print("Swaroop's address is %s" % ab['Swaroop'])  # 打印: swar


    # 添加值,或者設值

    ab['Guido'] = 'guido'


    # 刪除值

    del ab['Spammer']

    # ab.pop('Spammer') # 也可以用 pop 來刪除,但建議後面的這種寫法,避免沒有這個鍵時會報錯: ab.pop('Spammer', None)


    print('\nThere are %d contacts in the address-book\n' % len(ab)) # 打印: 3

    # 遍歷(這寫法得留意)

    for name, address in ab.items():

        print('Contact %s at %s' % (name, address))


    # 包含key

    if 'Guido' in ab: # 或者寫: if ab.has_key('Guido'):

        print("\nGuido's address is %s" % ab['Guido'])


    # 原字典上創建新字典

    print(ab) # 打印: {'Swaroop':'swar', 'Larry':'larry', 'Guido':'guido'}

    dd = dict(ab, slug_field='slug', test=5) # 創建新字典,字典作爲參數的只能放第一個,其餘不能再是字典;字典參數可省略

    print(dd) # 打印: {'Swaroop':'swar', 'test':5, 'slug_field':'slug', 'Larry':'larry', 'Guido':'guido'}


    # 建議的取值方法

    print( ab['test'] )  # 這樣取值,當字典裏面沒有對應的key時會報錯:“KeyError”

    print( ab.get('test', 'default_value') )  # get取值,當字典裏面沒有對應的key時可取後面的預設值,預設值是可選的(默認是 None)


    # 所有的鍵和值

    print(ab.keys())   # 所有的鍵

    print(ab.values()) # 所有的值


    # 複製(淺拷貝)

    print(ab.copy())

    # 複製(深拷貝)

    import copy

    c = copy.deepcopy(ab)



序列

    列表、元組和字符串都是序列,序列的兩個主要特點是“索引”操作符和“切片”操作符。

    索引操作符讓我們可以從序列中抓取一個特定項目。(即使用下標)

    切片操作符讓我們能夠獲取序列的一個切片,即一部分序列。(即在下標的中括號裏面使用冒號)


    例:

    shoplist = ['apple', 'mango', 'carrot', 'banana']


    # Indexing or 'Subscription' operation

    print('Item 0 is %s' % shoplist[0])

    print('Item 3 is %s' % shoplist[3])

    print('Item -1 is %s' % shoplist[-1])   # 打印:banana   即倒數第一個

    print('Item -2 is %s' % shoplist[-2])   # 打印:carrot   即倒數第二個


    # Slicing on a list

    print('Item 1 to 3 is %s' % shoplist[1:3])      # 打印:['mango', 'carrot']   即下標[1]到[3],包括開始但不包括結束

    print('Item 2 to end is %s' % shoplist[2:])     # 打印:['carrot', 'banana']  即下標[2]到結束,包括最後一個

    print('Item 1 to -1 is %s' % shoplist[1:-1])    # 打印:['mango', 'carrot']   即下標[1]到[-1],包括開始但不包括結束

    print('Item start to end is %s' % shoplist[:])  # 打印整個列表,跟直接寫“shoplist”效果一樣


    # Slicing on a string (string與列表有同樣的操作,)

    name = 'swaroop'

    print('characters 1 to 3 is %s' % name[1:3])     # 打印:wa

    print('characters 2 to end is %s' % name[2:])    # 打印:aroop

    print('characters 1 to -1 is %s' % name[1:-1])   # 打印:waroo

    print('characters start to end is %s' % name[:]) # 打印:swaroop  跟直接寫這個字符串一樣



參考(引用)

    當你創建一個對象並給它賦一個變量的時候,這個變量僅僅 參考 那個對象,而不是表示這個對象本身!

    也就是說,變量名指向你計算機中存儲那個對象的內存。

    這被稱作名稱到對象的綁定。


    例:

    shoplist = ['apple', 'mango', 'carrot', 'banana']

    mylist = shoplist # mylist 只是對象的另一個名稱,他們指向相同的內存空間


    del shoplist[0]


    # 他們此時打印相同的內容,都少了'apple'

    print('shoplist is', shoplist)

    print('mylist is', mylist)


    # 深拷貝,複製成另一個對象(得記住用切片操作符來取得拷貝)

    mylist = shoplist[:] # make a copy by doing a full slice

    del mylist[0] # remove first item


    # 注意,現在他們打印出不同的內容

    print('shoplist is', shoplist)

    print('mylist is', mylist)



列表綜合

    通過列表綜合,可以從一個已有的列表導出一個新的列表。

    [返回值 for 元素 in 列表 if 條件] 比如 [num for num in xrange(100) if num%2==0] 返回0~99之間的偶數列表


    # 例如,你有一個數的列表,而你想要得到一個對應的列表,使其中所有大於2的數都是原來的2倍。對於這種應用,列表綜合是最理想的方法。

    listone = [2, 3, 4]

    listtwo = [2*i for i in listone if i > 2] # 爲滿足條件(if i > 2)的數指定了一個操作(2*i),從而導出一個新的列表。

    print(listtwo) # 打印: [6, 8]


    ls=[1,3,5,7] # reduce 在python3去掉了

    print(reduce(lambda x,y:x+y,ls)) # 計算過程就是 1+3=4 然後4+5得到結果9,再加7,以此類推,最後返回最終計算的結果(總和);打印:16


    # 將字典的key,value倒過來的寫法:

    a_dict = {'a': 1, 'b': 2, 'c': 3}

    # python3 的寫法:

    b_dict = {value:key for key, value in a_dict.items()}

    # python2 時的寫法:

    b_dict = {}

    for key, value in a_dict.iteritems():

        b_dict[value] = key

    print(b_dict) # key與value翻轉,打印: {1:'a', 2:'b', 3:'c'}


    說明:

    注意原來的列表並沒有發生變化。

    在很多時候,我們都是使用循環來處理列表中的每一個元素,而使用列表綜合可以用一種更加精確、簡潔、清楚的方法完成相同的工作。


    小心 list 的 += 操作(python2時可以用,python3不可以再這樣用)



集合

    Python3 開始有這寫法,跟之前的差不多,只是用大括號括起來,如: a = {1, 'aa', 3, 5, 6}

    集合同樣可以使用綜合計算,如: a = {x for x in range(10) if x % 2 == 0}




成員測試 in, not in

    檢查是否包含有此內容,返回 True 或者 False, 例如:


    # 1.對字符串

    if 'a' in 'Swaroop':

        print('Yes, it contains the string "a"')


    # 2.對集合(列表、元組和字典)

    if 'genre' in ('genre', 'jazz'):

        print('Yes, it contains the genre')

    print('genre' in ('genre', 'jazz')) # 元組,打印: True

    print('genre' in ['genre', 'jazz']) # 列表,打印: True

    print('genre' in {'genre':'sss', 'jazz':'dddd'}) # 字典,檢查key,打印: True

    print('sss' in {'genre':'sss', 'jazz':'dddd'}) # 字典,打印: False



排序

    1.sort方法

      Python語言內置了sort方法,可以很方便地對某個List進行排序

      例如:

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

        L.sort()

        print(L) # 打印:[1, 2, 3, 4, 5, 6]

        li=[(2,'a'),(4,'b'),(1,'d')]

        li.sort() # 元組列表排序

        print(li) # 打印: [(1, 'd'), (2, 'a'), (4, 'b')]


    2.自定義排序(例如,按關鍵詞的權重排序,按人的年齡排序,等等)

      若List中每個元素都是2-tuple,tuple中第一個元素爲String類型的keyword,第二個元素爲該字符串對應的權重(int類型),希望按照權重排序(從高到低),則可以這樣:


        L = [('b', 1), ('a', 0), ('c', 2), ('d', 3)]

        # L.sort(lambda E1, E2: -cmp(E1[1], E2[1])) # cmp函數裏面是需比較的兩個值,負號表示倒序。(python2 的寫法)

        L.sort(key=lambda d:-d[1]) # Python3的寫法,由於去掉了cmp()函數,得傳入key參數; python2也可以這樣用;負號表示倒序

        print(L) # 打印:[('d', 3), ('c', 2), ('b', 1), ('a', 0)]


    3.dict排序

      對字典的排序,因爲每一個項包括一個鍵值對,所以要選擇可比較的鍵或值進行排序

        sorted(iterable[, cmp[, key[, reverse]]])

        # cmp 和 key 一般使用 lambda

        如:


        d={"ok":1,"no":2}

        # 對字典按鍵排序,用元組列表的形式返回

        print(sorted(d.items(), key=lambda a:a[0])) # 打印: [('no', 2), ('ok', 1)]

        print(sorted(d)) # 打印:['no', 'ok']

        print(d) # 原字典並未改變,打印:{'ok':1, 'no':2}

        # 對字典按值排序,用元組列表的形式返回

        print(sorted(d.items(), key=lambda d:d[1])) # 打印:[('ok', 1), ('no', 2)]


        # 排序後再轉成字典,就無法再保證排序了

        b = sorted(d.items(), key=lambda v:v[0])

        print(b) # 打印: [('no', 2), ('ok', 1)]

        print(dict(b)) # (排序又亂了)打印: {'ok': 1, 'no': 2}



    4.類的排序

        class test:

            def __init__(self,a,b):

                self.a = a

                self.b = b


        test1 = test(5,25)

        test2 = test(50,35)

        test3 = test(10,15)

        tests = [test1, test2, test3]


        # 以 cmp 來指定排序方式, python3不可以這樣寫(沒有cmp參數及cmp函數)

        result = sorted(tests,cmp = lambda x,y: cmp(x.a, y.a))

        # 遍歷排序結果,結果是已排序的: a:5  a:10  a:50

        for item in result:

            print("a:%s" % item.a)


        # 以 key 來排序,結果也是可以的

        result2 = sorted(tests,key = lambda d:d.a)

        for item in result2:

            print("a:%s" % item.a)


        # 遍歷原資料,原資料的順序沒有改變

        for item in tests:

            print("a:%s" % item.a)


    5.注意:

      python3 由於去掉了 cmp() 函數,可以用“(a > b) - (a < b)”代替“ cmp(a, b) ”


    6.冒泡算法,如下:

        num = [23,2,3,6,18,9,33,13,24,19]

        for i in range(len(num)-1):

            for j in range(len(num)-i-1):

                if (num[j] > num[j+1]):

                    num[j], num[j+1] = num[j+1], num[j] # 置換,這樣寫比較簡便,不需再用臨時變量

        print(num)



綜合實例:

    在Python中對列表,元組,字典等內置的數據結構的處理是很方便的事情,python借鑑了Lisp中的很多函數式計算的方法來處理列表,可以極大的簡化我們的代碼。

    1. set():  將元組,列表 轉化成沒有重複項的集合

    2. list(): 將集合,元組轉化成列表

    3. tuple(): 將集合,列表轉化成元組


    4. map(func,list):將list的每一個元素傳遞給func的函數,這個函數有一個參數,且返回一個值,map將每一次調用函數返回的值組成一個新列表返回

    5. filter(func,list):將list的每一個元素傳遞給func的函數,這個函數有一個參數,返回bool類型的值,filter將返回True的元素組成新列表返回

    6. reduce(func,list):將list的元素,挨個取出來和下一個元素通過func計算後將結果和再下一個元素繼續計算



    一、列表去重

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

        ls = list(set(ls)) # 最簡單的列表去除重複


        L = [1, 8, 3, 4, 6, 2, 3, 4, 5]

        kk = [x for x in L if x not in locals()['_[1]']] # 保留原順序的去除重複,只有 2.6 上可以, 2.7 以上版本不能這樣寫

        # '_[1]' 是個內部臨時變量,可查看:  [x for x, y in locals().items()]



    二、假如有列表:

        books = [

            {"name":"C#從入門到精通",  "price":23.7,  "store":"卓越"},

            {"name":"ASP.NET高級編程", "price":44.5,  "store":"卓越"},

            {"name":"C#從入門到精通",  "price":24.7,  "store":"噹噹"},

            {"name":"ASP.NET高級編程", "price":45.7,  "store":"噹噹"},

            {"name":"C#從入門到精通",  "price":26.7,  "store":"新華書店"},

            {"name":"ASP.NET高級編程", "price":55.7,  "store":"新華書店"},

        ]


        2.1 求《ASP.NET高級編程》價格最便宜的店:

        storename=min([b for b in books if b['name']=="ASP.NET高級編程"],key=lambda b:b['price'])["store"]

        過程:先用列表解析取出《ASP.NET高級編程》的列表,通過min函數,比較字典的price鍵獲取price最小的項



        2.2 求在新華書店購買兩本書一樣一本要花的錢:

        price=sum([b['price'] for b in books if b['store']=="新華書店"])



        2.3 求列表中有那幾本書:

        booknames=list(set([b['name'] for b in books]))



        2.4 列表裏的書都打5折:

        books=map(lambda b:dict(name=b['name'],price=b['price']*0.5,store=b['store']),books)



        2.5 《C#從入門到精通》的平均價格:

        avg=(lambda ls:sum(ls)/len(ls))([b['price'] for b in books if b['name']=="C#從入門到精通"])



        2.6 求每本書的平均價格:

        book_avg=map(lambda bookname:dict(name=bookname,avg=(lambda ls:sum(ls)/len(ls))([b['price'] for b in books if b['name']==bookname])),list(set([b['name'] for b in books])))


        這段代碼放在一行比較難看懂,但是格式化一下就很好懂了,構建的過程如下:


            step1: 要求每本書的平均價格,首先要得到共有幾本書,方法見2.3,得到去重的書名列表

            list(set([b['name'] for b in books])) #去重後的書名列表


            step2: 要求每一本書的均價,需要將計算均價的函數映射到每一本書上,於是

            map(

                #計算均價的函數,

                list(set([b['name'] for b in books])) #去重後的書名列表

            )


            step3: 加入計算單本書均價的函數,參考2.5的方法,由於只用一行,所以用lambda來搞定:

            func=lambda bookname:(lambda ls:sum(ls)/len(ls))([b.price for b in books if b['name']==bookname])


            step4: 將計算單本均價的lambda函數加入map中,得到最終結果:

            經過格式化後的結果,前面的單行代碼可以格式化爲下面容易閱讀的形式

            book_avg=map(

                lambda bookname:

                    dict(

                        name = bookname,

                        # 計算單本書均價的函數

                        avg  = (lambda ls:sum(ls)/len(ls)) ([b['price'] for b in books if b['name']==bookname])

                    ),

                #去重後的書名列表

                list(

                     set(

                         [b['name'] for b in books]

                     )

                )

            )



在函數中接收元組和列表(函數的參數數量可以變動,即可變長參數)

    當要使函數接收元組或字典形式的參數的時候,有一種特殊的方法,它分別使用*和**前綴。

    這種方法在函數需要獲取可變數量的參數的時候特別有用。

    而且,使用*和**前綴的參數還可以傳遞給其它函數。


    例:

    # 由於在args變量前有*前綴,所有多餘的函數參數都會作爲一個元組存儲在args中

    def sum(message, *args):

        '''Return the sum of each argument.'''

        total = 0

        # 除了用循環,也可以用下標來讀取參數,如: args[0]

        for i in args:

            total += i

        print (str(type(args)) + '  ' + message + ":" + str(total))

        sum2(args) # 這樣傳過去的 args 是一個元組;打印如: ((3, 5.5),)

        sum2(*args) # 這樣傳過去的 *args 表示多個參數;打印如:(3, 5.5)


    def sum2(*args):

        print(args)


    sum('hight', 3, 5.5) # 打印: <type 'tuple'>  hight:8.5

    sum('weight', 10)    # 打印: <type 'tuple'>  weight:10



    # 函數參數接收字典用法。使用的是**前綴,多餘的參數則會被認爲是一個字典的鍵/值對。

    def printDict(message, **args):

        print(str(type(args)) + '  ' + message + ':' + str(args))

        printDict2(args = args) # 可這樣,把 args 當做一個值(裏面是字典),傳過去;打印如: {'args': {'a': 3, 'b': 'dd'}}

        printDict2(**args) # 也可這樣,把 **args 看做傳過來的多個鍵/值對,傳過去;打印如:{'a': 3, 'b': 'dd'}


    def printDict2(**args):

        print(args)


    # 注意:參數爲字典時,參數裏面必須使用等號,否則運行出錯

    printDict('hight', a=3, b='dd') # 打印: <type 'dict'>  hight:{'a': 3, 'b': 'dd'}



    # 可以混合使用*和**前綴的參數, 但是必須 *args 在前, **args 在後,否則編譯不通過

    def printMul(message, *args1, **args2):

        print(message + '  args1:' + str(args1) + '  args2:' + str(args2))


    printMul('hello', 5, 4, a=2, b=3) # 打印: hello  args1:(5, 4)  args2:{'a': 2, 'b': 3}



面向對象的編程

    面向過程的編程:根據操作數據的函數或語句塊來設計程序的。

    面向對象的編程:把數據和功能結合起來,用稱爲對象的東西包裹起來組織程序的方法。

    類和對象是面向對象編程的兩個主要方面。“類”創建一個新類型,而“對象”是這個類的實例。

    域:屬於一個對象或類的變量。

    方法:屬於類的函數,被稱爲類的方法。

    域和方法可以合稱爲類的屬性。

    域有兩種類型——屬於每個實例/類的對象或屬於類本身。它們分別被稱爲實例變量和類變量。

    類使用class關鍵字創建。類的域和方法被列在一個縮進塊中。


self 參數

    類的方法與普通的函數只有一個特別的區別——它們“必須”有一個額外的第一個參數名稱,但是在調用這個方法的時候你不爲這個參數賦值,Python會提供這個值。這個特別的變量指對象本身,按照慣例它的名稱是self。

    雖然你可以給這個參數任何名稱,但是“強烈建議”使用self這個名稱——其他名稱都是不贊成使用的。

    使用一個標準的名稱有很多優點——1.方便別人閱讀;2.有些IDE(集成開發環境)也可以幫助你。

    Python中的self等價於C++中的self指針和Java、C#中的this參考。


    例:

    class Person:

        def sayHi(self):  # self參數必須寫

            print('Hello, how are you?')


    p = Person()

    p.sayHi() # self參數不需賦值

    print(p)  # 打印: <__main__.Person instance at 0xf6fcb18c>   (已經在__main__模塊中有了一個Person類的實例)



類的變量和對象的變量

    類的變量: 由一個類的所有對象(實例)共享使用。當某個對象對類的變量做了改動的時候,這個改動會反映到所有其他的實例上。

    對象的變量: 由類的每個對象/實例擁有。它們不是共享的,在同一個類的不同實例中,雖然對象的變量有相同的名稱,但是是互不相關的。

    使用的數據成員名稱以“雙下劃線前綴”且不是雙下劃線後綴,比如__privatevar,Python的名稱管理體系會有效地把它作爲私有變量。

    慣例: 如果某個變量只想在類或對象中使用,就應該以單下劃線前綴。而其他的名稱都將作爲公共的,可以被其他類/對象使用。


    例:

    class Person:

        '''Represents a person.'''

        population = 0 # 類的變量


        def __init__(self, name):

            '''Initializes the person's data.'''

            # 每創建一個對象都增加1

            Person.population += 1 # 調用類的變量,必須用 類名.變量名,如果寫 self.變量名 則是對象的變量了

            self.name = name # 對象的變量,每個對象獨立的

            print('(Initializing %s) We have %d persons here.' % (self.name, Person.population))


        def __del__(self):

            '''I am dying.'''

            print('%s says bye.' % self.name)

            Person.population -= 1


        def sayHi(self):

            self.__sayHi2() # 調用私有方法,外部不能調用的


        # 以雙下劃線開頭(但沒有雙下劃線結尾),則變成私有,僅供內部調用

        def __sayHi2(self): # 使用 self.population 也可以讀取類的變量,只是改變的時候卻只改變對象的變量

            print('Hi, my name is %s. We have %d persons here.' % (self.name, self.population))


    swaroop = Person('Swaroop')

    swaroop.sayHi() # 打印: Swaroop, 1


    kalam = Person('Abdul Kalam')

    kalam.sayHi() # 打印: Abdul Kalam, 2


    swaroop.sayHi() # 打印: Swaroop, 2

    print(Person.population) # 打印: 2

    del swaroop # 調用對象的 __del__ 方法

    print(Person.population) # 打印: 1


    print(Person.__doc__) # 打印類的docstring

    print(Person.__init__.__doc__) # 打印類的方法的docstring



繼承

    多態現象:一個子類型在任何需要父類型的場合可以被替換成父類型,即對象可以被視作是父類的實例。

    被繼承的類被稱爲“基本類”或“超類”、“父類”。繼承的類被稱爲“導出類”或“子類”。


    例:

    # 父類

    class Member:

        def __init__(self, name, age):

            self.name = name

            self.age = age

            print('(Initialized Member: %s)' % self.name)


        def tell(self):

            print('Member Name:"%s" Age:"%s"' % (self.name, self.age))


        def tell2(self):

            print('Member haha...')


    # 子類

    class Student(Member): # 繼承的父類寫括號裏面;多繼承則寫多個,這括號的稱爲繼承元組

        def __init__(self, name, age, marks):

            Member.__init__(self, name, age) # 父類的初始化,需手動寫;Python不會自動調用父類的constructor

            self.marks = marks

            print('(Initialized Student: %s)' % self.name)


        def tell(self):

            Member.tell(self) # 調用父類的方法,注意:方法調用之前要加上父類名稱前綴,然後把self變量及其他參數傳遞給它。

            print('Marks: "%d"' % self.marks)


    s = Student('Swaroop', 22, 75)

    s.tell() # 會調用子類的方法

    s.tell2() # 子類沒有的,則使用父類的;如果多繼承,且父類都有這個方法,則使用繼承元組中排前面的



特殊的方法

__init__ 方法

    __init__ 方法在類的一個對象被建立時,馬上運行。用來對你的對象做初始化。

    注意,這個名稱的開始和結尾都是雙下劃線。( __init__ 方法類似於C++、C#和Java中的 constructor )


    例:

    class Person:

        def __init__(self, name):

            self.test_name = name

        def sayHi(self):

            print('Hello, my name is ' + self.test_name)

            self.test = 'sss'  # 屬性可以隨處定義,不需事先定義

            print('the test is ' + self.test)


    p = Person('Swaroop')

    p.sayHi() # 打印: Swaroop , sss

    print('the Person test is ' + p.test) # 打印: sss

    p.test2 = 'haha...'

    print('the Person test2 is ' + p.test2) # 打印: haha...


    名稱   說明

    __init__(self,...) 這個方法在新建對象恰好要被返回使用之前被調用。

    __del__(self) 在對象要被刪除之前調用。如使用 del 刪除時。

    __str__(self) 在我們對對象使用 print 語句或是使用 str() 的時候調用。

    __lt__(self,other) 當使用 小於 運算符 (<) 的時候調用。

    __gt__(self,other) 當使用 大於 運算符 (>) 的時候調用。

    __eq__(self,other) 當使用 等於 運算符 (==) 的時候調用。

    __ne__(self,other) 當使用 不等於 運算符 (!=) 的時候調用。

    __le__(self,other) 當使用 小於等於 運算符 (<=) 的時候調用。

    __ge__(self,other) 當使用 大於等於 運算符 (>=) 的時候調用。

    __add__(self,other)當使用 加 運算符 (+) 的時候調用。

    __getitem__(self,key) 使用x[key]索引操作符的時候調用。

    __len__(self) 對序列對象使用內建的 len() 函數的時候調用。



try ... except (處理異常)

    使用 try ... except 語句來處理異常。

    except 從句可以專門處理單一的錯誤或異常,或者一組包括在圓括號內的錯誤/異常。沒有給出錯誤或異常的名稱,則處理所有的錯誤和異常。

    如果某個錯誤或異常沒有被處理,默認的Python處理器就會被調用。它會終止程序的運行,並且打印一個消息。

    還可以關聯上一個 else 從句,當沒有異常發生的時候執行。


    常見異常(可避免的):

        使用不存在的字典關鍵字 將引發 KeyError 異常。

        搜索列表中不存在的值 將引發 ValueError 異常。

        調用不存在的方法 將引發 AttributeError 異常。

        引用不存在的變量 將引發 NameError 異常。

        未強制轉換就混用數據類型 將引發 TypeError 異常。

        導入一個並不存在的模塊將引發一個 ImportError 異常。


try ... finally

    假如希望在無論異常發生與否的情況下都執行一段代碼,可以使用 finally 塊來完成。

    注意,在一個 try 塊下,你可以同時使用 except 從句和 finally 塊。

    如果在 finally 前面的 try 或者 except, else 等裏面有 return 語句,會先跳去執行 finally 再執行 return


raise 語句

    可以使用 raise 語句引發異常(拋出異常)。你還得指明錯誤/異常的名稱和伴隨異常觸發的異常對象。

    可以引發 Error 或 Exception 類的直接或間接導出類。


    在Python 3裏,拋出自定義異常的語法有細微的變化。

        Python 2                                        Python 3

    ① raise MyException                                MyException

    ② raise MyException, 'error message'               raise MyException('error message')

    ③ raise MyException, 'error message', a_traceback  raise MyException('error message').with_traceback(a_traceback)

    ④ raise 'error message'                            unsupported(不支持)

    說明:

    ① 拋出不帶自定義錯誤信息的異常,這種最簡單的形式下,語法沒有改變。

    ② 拋出帶自定義錯誤信息的異常時:Python 2用一個逗號來分隔異常類和錯誤信息;Python 3把錯誤信息作爲參數傳遞給異常類。

    ③ 拋出一個帶用戶自定義回溯(stack trace,堆棧追蹤)的異常。在Python 2和3裏這語法完全不同。

    ④ 在Python 2裏,可以僅僅拋出一個異常信息。在Python 3裏,這種形式不再被支持。2to3將會警告你它不能自動修復這種語法。


    例:

    raise RuntimeError("有異常發生")



生成器的 throw 方法

    在Python 2裏,生成器有一個 throw()方法。

    調用 a_generator.throw()會在生成器被暫停的時候拋出一個異常,然後返回由生成器函數獲取的下一個值。


       Python 2                                         Python 3

    ① a_generator.throw(MyException)                   a_generator.throw(MyException) # 沒有變化

    ② a_generator.throw(MyException, 'error message')  a_generator.throw(MyException('error message'))

    ③ a_generator.throw('error message')               unsupported(不支持)

    說明:

    ① 最簡單的形式下,生成器拋出不帶用戶自定義錯誤信息的異常。這種情況下,從Python 2到Python 3語法上沒有變化 。

    ② 如果生成器拋出一個帶用戶自定義錯誤信息的異常,你需要將這個錯誤信息字符串(error string)傳遞給異常類來以實例化它。

    ③ Python 2還支持拋出只有異常信息的異常。Python 3不支持這種語法,並且2to3會顯示一個警告信息,告訴你需要手動地來修復這處代碼。


    例(3.x)語法:

    # 定義一個異常類,繼承 Exception

    class ShortInputException(Exception):

        '''A user-defined exception class.'''

        def __init__(self, length, atleast):

            Exception.__init__(self)

            self.length = length

            self.atleast = atleast


    try:

        s = input('Enter something --> ') # Python 2 的輸入是 raw_input()

        if len(s) < 3:

            raise ShortInputException(len(s), 3) # 引發異常;Python 2可以寫:raise ShortInputException,(len(s), 3)

    # 捕獲 EOFError 異常

    except EOFError:

        print('\nWhy did you do an EOF on me?')

    # 捕獲一組錯誤/異常,Python 2 時應該寫: “except (RuntimeError, ImportError), e:”

    except (RuntimeError, ImportError) as e:

        pass

    # Python 2 時應該寫: “except ShortInputException, x:”

    except ShortInputException as x:

        print('ShortInputException: The input was of length %d,\

              was expecting at least %d' % (x.length, x.atleast))

    # 捕獲所有異常

    except:

        print('\nWhy did you do an Exception on me?')

    # 沒有任何異常時執行

    else:

        print('No exception was raised.')

    # 不管是否有異常,都會執行

    finally:

        print('finally .....')




lambda 形式

    lambda 語句被用來創建新的函數對象,並且在運行時返回它們。

    注意, lambda 形式中,只能使用表達式。


    例:

    def make_repeater(n):

        return lambda s: s*n    # 注意: lambda 返回的是函數,而不是表達式的值


    # 注意, twice 接收的是函數, 而不是表達式的值, 所以 twice 是一個函數,而不是值

    twice = make_repeater(2)

    print(twice('word '))       # 因爲 twice 是一個函數,這裏是調用這個函數,打印結果: word word


    print(make_repeater(3)(5))  # 這裏的“make_repeater(3)”可以認爲是匿名函數,打印結果: 15



    # 上面例子貌似太過複雜,下面是簡單點的寫法

    # 記住, twice2 是一個函數

    twice2 = lambda s: s*2


    print(twice2('word '))  # 打印: word word

    print(twice2(5))        # 打印: 10


    # 上面的 twice2 相當於正常的函數這樣寫(lambda 後面的是參數,而結果是返回冒號後面的表達式):

    def twice3(s):

        return s*2


    print(twice3('word '))  # 打印: word word

    print(twice3(5))        # 打印: 10



    # 可認爲 lambda 是一個匿名函數

    print((lambda s: s*2)('word '))  # 打印: word word


    # 而 def 是不能申明匿名函數的

    print((def (s): return s*2)(10)) # 這寫法將會報錯

    print((def twice3(s): return s*2)(10)) # 這寫法也同樣會報錯



    # lambda 可以有多個參數

    twice4 = lambda x,y: x*y

    print(twice4('word ', 3))  # 打印: word word word

    print(twice4(5, 3))        # 打印: 15



exec 和 eval

    exec 用來執行儲存在字符串或文件中的Python語句。

    eval 用來計算存儲在字符串中的有效Python表達式。

    exec 跟 eval 是相似的,但是 exec 更加強大並更具有技巧性。

    eval 只能執行單獨一條表達式;但是 exec 能夠執行多條語句,導入(import),函數聲明

    實際上 exec 能執行整個Python程序的字符串。


    Python 2 與 Python 3 的比較

            Python 2                                              Python 3

        ① exec codeString                                       exec(codeString)

        ② exec codeString in global_namespace                   exec(codeString, global_namespace)

        ③ exec codeString in global_namespace, local_namespace  exec(codeString, global_namespace, local_namespace)

    說明:

        ① 就像 print 語句在Python 3裏變成了一個函數一樣, exec 語句在Python 3裏也變成一個函數。

        ② exec 可以指定名字空間,代碼將在這個由全局對象組成的私有空間裏執行。

        ③ exec 還可以指定一個本地名字空間(比如一個函數裏聲明的變量)。


    例:

    exec('print("Hello World")')  # 執行打印語句

    print(eval('2*3'))  # 打印:6



execfile 語句

    Python 2裏的 execfile 語句也可以像執行Python代碼那樣使用字符串。不同的是 exec 使用字符串,而 execfile 則使用文件。

    在Python 3裏,execfile 語句已經被去掉了。如果你真的想要執行一個文件裏的Python代碼(但是你不想導入它),你可以通過打開這個文件,讀取它的內容,然後調用 compile()全局函數強制Python解釋器編譯代碼,然後調用 exec() 函數。


    Python 2 寫的: execfile('a_filename')

    Python 3 寫的: exec(compile(open('a_filename', 'rb').read(), 'a_filename', 'exec'))



assert 語句

    assert 語句用來聲明某個條件是真的。

    當 assert 語句失敗的時候,會引發一個 AssertionError 錯誤。

    比較常用於檢驗錯誤。


    例:

    assert 2 >= 1  # 正常運行

    assert 0 >= 1  # 出現錯誤



repr 函數

    repr 函數用來取得對象的規範字符串表示。反引號(也稱轉換符)可以完成相同的功能。

    注意,在大多數時候有 eval(repr(object)) == object。

    基本上, repr 函數和反引號用來獲取對象的可打印的表示形式。

    你可以通過定義類的 __repr__ 方法來控制你的對象在被repr函數調用的時候返回的內容。


    例:

    i = ["item"]

    print(repr(i)) # 打印:['item']



yield 用法

    1) 包含 yield 的函數是一個 Generator, 與平常的函數不同


    例:

        def gen():

            print 'enter'

            yield 1

            print 'next'

            yield 2

            print 'next end'


        print('begin...')

        gen() # 直接調用,發現打印沒有執行(與平常的函數不同)

        # 從容器裏拿到 iterator 的時候它還什麼也不是,處在容器入口處,對於數組來說就是下標爲-1的地方,對於函數來說就是函數入口嘛事沒幹,但是萬事俱備就欠 next 。

        print('end...')


        print

        for i in gen():

            print('...%d...' % i)


        # 開始 for in , next 讓 itreator 爬行到 yield 語句存在的地方並返回值,

        # 再次 next 就再爬到下一個 yield 語句存在的地方並返回值,依次這樣直到函數返回(容器盡頭)。


    上面代碼的輸出是:

        begin...

        end...


        enter

        ...1...

        next

        ...2...

        next end



    2) Generator 裏面的 send(msg) 與 next()

        調用 for in 時,相當於是使用 next() 語句或是 send(None)

        如果沒有接收值則使用 send 發送的值必須是 None ,否則會出錯的,因爲 yield 語句沒有接收這個值,但 send 又必須傳參數的。


    例,用上例的 gen() 函數

        c = gen()

        print(c.next()) # 調用第一個 yield

        print(c.send(None)) # 調用第二個 yield, 這裏 next() 與 send(None) 是同樣效果的

        print(c.next()) # 第三次調用則出錯了,因爲數組下標越界, 拋出 StopIteration 的異常; 但會把最後的“next end”打印出來,前兩個是沒法把它打印出來的



        # send(msg) 貌似沒法把 msg 傳到參數中

        def gen2(m):

            for i in range(10):

                print(m)

                yield i + 101


        d = gen2('***')

        print(c.next())

        print(c.send(5555)) # 打印的依然是 ***, 而不是 5555



    3) throw() 與 close() 中斷 Generator

        中斷 Generator 是一個非常靈活的技巧,可以通過 throw 拋出一個 GeneratorExit 異常來終止 Generator 。 Close() 方法作用是一樣的,其實內部它是調用了 throw(GeneratorExit) 的。我們看:


        def close(self):

            try:

                self.throw(GeneratorExit)

            except (GeneratorExit, StopIteration):

                pass

            else:

                raise RuntimeError("generator ignored GeneratorExit")  # Other exceptions are not caught


    因此,當我們調用了 close() 方法後,再調用 next() 或是 send(msg) 的話會拋出一個異常

    例,繼續用前面例的 gen() 函數

        c = gen()

        print(c.next()) # 調用第一個 yield

        c.close()

        print(c.next()) # 調用第二個 yield 出錯了,拋出 StopIteration 的異常, 因爲前面的 close 已經關閉它了




正則表達式

    正則表達式有強大並且標準化的方法來處理字符串查找、替換以及用複雜模式來解析文本。

    正則表達式的語法比程序代碼更緊湊,格式更嚴格,比用組合調用字符串處理函數的方法更具有可讀性。

    還可以在正則表達式中嵌入註釋信息,這樣就可以使它有自文檔化的功能。


    匹配符:

        ^       匹配字符串開始位置。在多行字符串模式匹配每一行的開頭。

        $       匹配字符串結束位置。在多行字符串模式匹配每一行的結尾。

        .       匹配除了換行符外的任何字符,在 alternate 模式(re.DOTALL)下它甚至可以匹配換行。

        \A      匹配字符串開頭

        \Z      匹配字符串結尾

        \b      匹配一個單詞邊界。即 \w 與 \W 之間。

        \B      匹配一個非單詞邊界;相當於類 [^\b]。

        \d      匹配一個數字。

        \D      匹配一個任意的非數字字符。

        \s      匹配任何空白字符;它相當於類  [ \t\n\r\f\v]。

        \S      匹配任何非空白字符;它相當於類 [^ \t\n\r\f\v]。

        \w      匹配任何字母數字字符;它相當於類 [a-zA-Z0-9_]。

        \W      匹配任何非字母數字字符;它相當於類 [^a-zA-Z0-9_]。

        x?      匹配可選的x字符。即是0個或者1個x字符。

        x*      匹配0個或更多的x。

        x+      匹配1個或者更多x。

        x{n,m}  匹配n到m個x,至少n個,不能超過m個。

        (a|b|c) 匹配單獨的任意一個a或者b或者c。

        (x)     捕獲組,小括號括起來即可,它會記憶它匹配到的字符串。

                可以用 re.search() 返回的匹配對象的 groups()函數來獲取到匹配的值。

        \1      記憶組,它表示記住的第一個分組;如果有超過一個的記憶分組,可以使用 \2 和 \3 等等。

                記憶組的內容也要小括號括起來。

        (?iLmsux)          iLmsux的每個字符代表一種匹配模式

            re.I(re.IGNORECASE): 忽略大小寫(括號內是完整寫法,下同)

            re.M(re.MULTILINE): 多行模式,改變'^'和'$'的行爲(參見上圖)

            re.S(re.DOTALL): 點任意匹配模式,改變'.'的行爲

            re.L(re.LOCALE): 使預定字符類 \w \W \b \B \s \S 取決於當前區域設定

            re.U(re.UNICODE): 使預定字符類 \w \W \b \B \s \S \d \D 取決於unicode定義的字符屬性

            re.X(re.VERBOSE): 鬆散正則表達式模式。這個模式下正則表達式可以是多行,忽略空白字符,並可以加入註釋。

        (?:表達式)         無捕獲組。與捕獲組表現一樣,只是沒有內容。

        (?P<name>表達式)   命名組。與記憶組一樣,只是多了個名稱。

        (?P=name)          命名組的逆向引用。

        (?#...)            “#”後面的將會作爲註釋而忽略掉。例如:“ab(?#comment)cd”匹配“abcd”

        (?=...)            之後的字符串需要匹配表達式才能成功匹配。不消耗字符串內容。 例:“a(?=\d)”匹配“a12”中的“a”

        (?!...)            之後的字符串需要不匹配表達式才能成功匹配。不消耗字符串內容。 例:“a(?!\d)”匹配“abc”中的“a”

        (?<=...)           之前的字符串需要匹配表達式才能成功匹配。不消耗字符串內容。 例:“(?<=\d)a”匹配“2a”中的“a”

        (?<!...)           之前的字符串需要不匹配表達式才能成功匹配。不消耗字符串內容。 例:“(?<!\d)a”匹配“sa”中的“a”

                           注:上面4個表達式的裏面匹配的內容只能是一個字符,多個則報錯。

        (?(id/name)yes-pattern|no-pattern)  如果編號爲 id 或者別名爲 name 的組匹配到字符串,則需要匹配yes-pattern,否則需要匹配no-pattern。 “|no-pattern”可以省略。如:“(\d)ab(?(1)\d|c)”匹配到“1ab2”和“abc”


    元字符:

        "[" 和 "]"

            它們常用來匹配一個字符集。字符可以單個列出,也可以用“-”號分隔的兩個給定字符來表示一個字符區間。

                例如,[abc] 將匹配"a", "b", 或 "c"中的任意一個字符;也可以用區間[a-c]來表示同一字符集,和前者效果一致。

            元字符在類別裏並不起作用。例如,[a$]將匹配字符"a" 或 "$" 中的任意一個;"$" 在這裏恢復成普通字符。

            也可以用補集來匹配不在區間範圍內的字符。其做法是把"^"作爲類別的首個字符;其它地方的"^"只會簡單匹配 "^"字符本身。

                例如,[^5] 將匹配除 "5" 之外的任意字符。

            特殊字符都可以包含在一個字符類中。如,[\s,.]字符類將匹配任何空白字符或","或"."。

        反斜槓 "\"。

            做爲 Python 中的字符串字母,反斜槓後面可以加不同的字符以表示不同特殊意義。

            它也可以用於取消所有的元字符,這樣你就可以在模式中匹配它們了。

                例如,需要匹配字符 "[" 或 "\",可以在它們之前用反斜槓來取消它們的特殊意義: \[ 或 \\。


    建議使用原始字符串:

        建議在處理正則表達式的時候總是使用原始字符串。如: r'\bROAD$', 而不要寫成 '\\bROAD$'

        否則,會因爲理解正則表達式而消耗大量時間(正則表達式本身就已經夠讓人困惑的了)。


    無捕獲組:

        有時你想用一個組去收集正則表達式的一部分,但又對組的內容不感興趣。你可以用一個無捕獲組“(?:...)”來實現這項功能。

        除了捕獲匹配組的內容之外,無捕獲組與捕獲組表現完全一樣;可以在其中放置任何字符、匹配符,可以在其他組(無捕獲組與捕獲組)中嵌套它。

        無捕獲組對於修改已有組尤其有用,因爲可以不用改變所有其他組號的情況下添加一個新組。

        捕獲組和無捕獲組在搜索效率方面也一樣。


    命名組:

        與用數字指定組不同的是,它可以用名字來指定。除了該組有個名字之外,命名組也同捕獲組是相同的。

        (?P<name>...) 定義一個命名組,(?P=name) 則是對命名組的逆向引用。

        MatchObject 的方法處理捕獲組時接受的要麼是表示組號的整數,要麼是包含組名的字符串。所以命名組可以通過數字或者名稱兩種方式來得到一個組的信息。


    鬆散正則表達式:

        爲了方便閱讀和維護,可以使用鬆散正則表達式,它與普通緊湊的正則表達式有兩點不同:

        1, 空白符被忽略。空格、製表符(tab)和回車會被忽略。如果需要匹配他們,可以在前面加一個“\”來轉義。

        2, 註釋被忽略。註釋以“#”開頭直到行尾,與python代碼中的一樣。

        使用鬆散正則表達式,需要傳遞一個叫 re.VERBOSE的 參數。詳細見下面例子。


    例如:


        # 必須引入 re 標準庫

        import re


        # 字符串替換:  sub() 與 subn()

        s = '100 NORTH MAIN ROAD'

        # 將字符串結尾的單詞“ROAD”替換成“RD.”;該 re.sub() 函數執行基於正則表達式的字符串替換。

        print(re.sub(r'\bROAD$', 'RD.', s)) # 打印: 100 NORTH MAIN RD.

        ## subn() 與 sub() 作用一樣,但返回的是包含新字符串和替換執行次數的兩元組。

        print(re.subn(r'\bROAD$', 'RD.', s)) # 打印: ('100 NORTH MAIN RD.', 1)


        # 字符串分割, split()

        # 在正則表達式匹配的地方將字符串分片,將返回列表。只支持空白符和固定字符串。可指定最大分割次數,不指定將全部分割。

        print(re.split(r'\s+', 'this is a test')) # 打印: ['this', 'is', 'a', 'test']

        print(re.split(r'\W+', 'This is a test.', 2)) # 指定分割次數,打印:['this', 'is', 'a test']

        # 如果你不僅對定界符之間的文本感興趣,也需要知道定界符是什麼。在 RE 中使用捕獲括號,就會同時傳回他們的值。

        print(re.split(r'(\W+)', 'This is a test.', 2)) # 捕獲定界符,打印:['this', ' ', 'is', ' ', 'a test']


        ## `MatchObject` 實例的幾個方法

        r = re.search(r'\bR(OA)(D)\b', s)

        print(r.groups()) # 返回一個包含字符串的元組,可用下標取元組的內容,打印: ('OA', 'D')

        print(r.group())  # 返回正則表達式匹配的字符串,打印: ROAD

        print(r.group(2)) # 返回捕獲組對應的內容(用數字指明第幾個捕獲組),打印: D

        print(r.start())  # 返回匹配字符串開始的索引, 打印: 15

        print(r.end())    # 返回匹配字符串結束的索引,打印: 19

        print(r.span())   # 返回一個元組包含匹配字符串 (開始,結束) 的索引,打印: (15, 19)


        # 匹配多個內容, findall() 返回一個匹配字符串行表

        p = re.compile('\d+')

        s0 = '12 drummers drumming, 11 pipers piping, 10 lords a-leaping'

        print(p.findall(s0)) # 打印: [12, 11, 10]

        print(re.findall(r'\d+', s0)) # 也可這樣寫,打印: [12, 11, 10]


        # 匹配多個內容, finditer() 以迭代器返回

        iterator = p.finditer(s0)

        # iterator = re.finditer(r'\d+', s0) # 上句也可以這樣寫

        for match in iterator:

            print(match.group()) # 三次分別打印:12、 11、 10


        # 記憶組

        print(re.sub('([^aeiou])y$', 'ies', 'vacancy'))    # 將匹配的最後兩個字母替換掉,打印: vacanies

        print(re.sub('([^aeiou])y$', r'\1ies', 'vacancy')) # 將匹配的最後一個字母替換掉,記憶住前一個(小括號那部分),打印: vacancies

        print(re.search('([^aeiou])y$', 'vacancy').group(1)) # 使用 group() 函數獲取對應的記憶組內容,打印: c


        # 記憶組(匹配重複字符串)

        p = re.compile(r'(?P<word>\b\w+)\s+\1') # 注意, re.match() 函數不能這樣用,會返回 None

        p = p.search('Paris in the the spring')

        # p = re.search(r'(?P<word>\b\w+)\s+\1', 'Paris in the the spring') # 這一句可以替換上面兩句

        print(p.group())  # 返回正則表達式匹配的所有內容,打印: the the

        print(p.groups()) # 返回一個包含字符串的元組,打印: ('the',)


        # 捕獲組

        r = re.search(r'\bR(OA)(D)\b', s) # 如過能匹配到,返回一個 SRE_Match 類(正則表達式匹配對象);匹配不到則返回“None”

        # `MatchObject` 實例的幾個方法

        if r: # 如果匹配不到,則 r 爲 None,直接執行下面語句則會報錯;這裏先判斷一下,避免這錯誤

            print(r.groups()) # 返回一個包含字符串的元組,可用下標取元組的內容,打印: ('OA', 'D')

            print(r.group())  # 返回正則表達式匹配的字符串,打印: ROAD

            print(r.group(2)) # 返回捕獲組對應的內容(用數字指明第幾個捕獲組),打印: D


        # 無捕獲組

        print(re.match("([abc])+", "abcdefab").groups())   # 正常捕獲的結果: ('c',)

        print(re.match("(?:[abc])+", "abcdefab").groups()) # 無捕獲組的結果: ()


        # 命名組

        m = re.match(r'(?P<word>\b\w+\b) *(?P<word2>\b\w+\b)', 'Lots of punctuation')

        print(m.groups())       # 返回正則表達式匹配的所有內容,打印:('Lots', 'of')

        print(m.group(1))       # 通過數字得到對應組的信息,打印: Lots

        print(m.group('word2')) # 通過名稱得到對應組的信息,打印: of


        # 命名組 逆向引用

        p = re.compile(r'(?P<word>\b\w+)\s+(?P=word)') # 與記憶組一樣用法, re.match() 函數同樣不能這樣用,會返回 None

        p = p.search('Paris in the the spring') #  r'(?P<word>\b\w+)\s+(?P=word)' 與 r'(?P<word>\b\w+)\s+\1' 效果一樣

        print(p.group())  # 返回正則表達式匹配的所有內容,打印: the the

        print(p.groups()) # 返回一個包含字符串的元組,打印: ('the',)


        # 使用鬆散正則表達式,以判斷羅馬數字爲例

        pattern = '''

            ^                   # beginning of string

            (M{0,3})            # thousands - 0 to 3 Ms

            (CM|CD|D?C{0,3})    # hundreds - 900 (CM), 400 (CD), 0-300 (0 to 3 Cs),

                                #            or 500-800 (D, followed by 0 to 3 Cs)

            (XC|XL|L?X{0,3})    # tens - 90 (XC), 40 (XL), 0-30 (0 to 3 Xs),

                                #        or 50-80 (L, followed by 0 to 3 Xs)

            (IX|IV|V?I{0,3})    # ones - 9 (IX), 4 (IV), 0-3 (0 to 3 Is),

                                #        or 5-8 (V, followed by 0 to 3 Is)

            $                   # end of string

            '''

        print(re.search(pattern, 'M')) # 這個沒有申明爲鬆散正則表達式,按普通的來處理了,打印: None

        print(re.search(pattern, 'M', re.VERBOSE).groups()) # 打印: ('M', '', '', '')


        # (?iLmsux) 用法

        # 以下這三句的寫法都是一樣的效果,表示忽略大小寫,打印: ['aa', 'AA']

        print(re.findall(r'(?i)(aa)', 'aa kkAAK s'))

        print(re.findall(r'(aa)', 'aa kkAAK s', re.I))

        print(re.findall(r'(aa)', 'aa kkAAK s', re.IGNORECASE))

        # 可以多種模式同時生效

        print(re.findall(r'(?im)(aa)', 'aa kkAAK s'))  # 直接在正則表達式裏面寫

        print(re.findall(r'(aa)', 'aa kkAAK s', re.I | re.M)) # 在參數裏面寫

        print(re.findall(r'(aa)', 'aa kkAAK s', re.I or re.M))


        # 預編譯正則表達式解析的寫法

        # romPattern = re.compile(pattern)  # 如果不是鬆散正則表達式,則這樣寫,即少寫 re.VERBOSE 參數

        romPattern = re.compile(pattern, re.VERBOSE)

        print(romPattern.search('MCMLXXXIX').groups()) # 打印: ('M', 'CM', 'LXXX', 'IX')

        print(romPattern.search('MMMDCCCLXXXVIII').groups()) # 打印: ('MMM', 'DCCC', 'LXXX', 'VIII')

        # match()、search()、sub()、findall() 等等都可以這樣用


    match() vs search()

        match() 函數只檢查 RE 是否在字符串開始處匹配,而 search() 則是掃描整個字符串。記住這一區別是重要的。

        match() 只報告一次成功的匹配,它將從 0 處開始;如果匹配不是從 0 開始的, match() 將不會報告它。

        search() 將掃描整個字符串,並報告它找到的第一個匹配。

    例:

        print(re.match('super', 'superstition').span())  # 打印: (0, 5)

        print(re.match('super', 'insuperable'))          # 打印: None

        print(re.search('super', 'superstition').span()) # 打印: (0, 5)

        print(re.search('super', 'insuperable').span())  # 打印: (2, 7)



Python標準庫:


os 模塊

    這個模塊包含普遍的操作系統功能。如果你希望你的程序能夠與平臺無關的話,這個模塊是尤爲重要的。

    os.sep  獲取操作系統特定的路徑分割符。比如在Linux、Unix下它是'/',在Windows下它是'\\',而在Mac OS下它是':'。

    os.name 字符串指示你正在使用的平臺。比如對於Windows,它是'nt',而對於Linux/Unix用戶,它是'posix'。

    os.getcwd() 函數得到當前工作目錄,即當前Python腳本工作的目錄路徑。

    os.getenv(key) 函數用來讀取環境變量。

    os.putenv(key, value) 函數用來設置環境變量。

    os.listdir(path) 返回指定目錄下的所有文件和目錄名。

    os.remove(filePath) 函數用來刪除一個文件。

    os.system(shellStr) 函數用來運行shell命令,windows平臺則是運行批處理命令。

    os.linesep  字符串給出當前平臺使用的行終止符。例如,Windows使用'\r\n',Linux使用'\n'而Mac使用'\r'。

    os.path.split(pathname)  函數返回一個路徑的目錄名和文件名。

    os.path.isfile(path) 函數檢驗給出的路徑是否一個文件。

    os.path.isdir(path)  函數分別檢驗給出的路徑是否目錄。

    os.path.existe(path) 函數用來檢驗給出的路徑是否真地存在。



unittest 模塊(單元測試)

    單元測試的好處:

      在編寫代碼之前,通過編寫單元測試來強迫你使用有用的方式細化你的需求。

      在編寫代碼時,單元測試可以使你避免過度編碼。當所有測試用例通過時,實現的方法就完成了。

      重構代碼時,單元測試用例有助於證明新版本的代碼跟老版本功能是一致的。

      在維護代碼期間,可驗證代碼是否破壞原有代碼的狀態。

      在團隊編碼中,縝密的測試套件可以降低你的代碼影響別人代碼的機率,提前發現代碼與其他人的不可以良好工作。

    單元測試的原則:

      完全自動運行,而不需要人工干預。單元測試幾乎是全自動的。

      自主判斷被測試的方法是通過還是失敗,而不需要人工解釋結果。

      獨立運行,而不依賴其它測試用例(即使測試的是同樣的方法)。即,每一個測試用例都是一個孤島。


    例:


        #### roman1.py 文件的內容  ####


        # 定義異常類型(這裏僅做範例,不執行什麼)

        class OutOfRangeError(ValueError): pass

        class NotIntegerError(ValueError): pass


        roman_numeral_map = (('M',  1000),

             ('CM', 900), ('D',  500), ('CD', 400), ('C',  100),

             ('XC', 90),  ('L',  50),  ('XL', 40),  ('X',  10),

             ('IX', 9),   ('V',  5),   ('IV', 4),   ('I',  1))


        # 被測試函數

        def to_roman(n):

            '''convert integer to Roman numeral'''

            # 數值範圍判斷

            if not ( 0 < n < 4000 ):

                raise OutOfRangeError('number out of range (must be less than 4000)')

            # 類型判斷, 內建的 isinstance() 方法可以檢查變量的類型

            # isinstance(n, int) 與 type(n) is int 等效

            if not isinstance(n, int):

                raise NotIntegerError('non-integers can not be converted')

            result = ''

            for numeral, integer in roman_numeral_map:

                while n >= integer:

                    result += numeral

                    n -= integer

            return result




        #### 測試文件的內容 ####


        import roman1 # 導入被測試的類

        import unittest


        # 需繼承 unittest 模塊的TestCase 類。TestCase 提供了很多可以用於測試特定條件的有用的方法。

        class KnownValues(unittest.TestCase):

            def setUp(self):

                """初始化"""

                #執行數據庫連接,數據初始化等,此函數可不寫

                pass


            # setUp 和 tearDown 在執行每個測試函數的前後都會執行

            def tearDown(self):

                """銷燬"""

                pass


            # 每一個獨立的測試都有它自己的不含參數及沒有返回值的方法。如果方法不拋出異常而正常退出則認爲測試通過;否則,測試失敗。

            # 測試本身是類一個方法,並且該方法以 test 開頭命名。如果不是 test 開頭,則不會執行。

            def test_to_roman_known_values(self):

                # 對於每一個測試用例, unittest 模塊會打印出測試方法的 docstring ,並且說明該測試失敗還是成功。

                # 失敗時必然打印docstring, 成功時需使用“-v”命令行參數來查看。

                '''to_roman 方法傳回的值與用例的數據不相等時,則測試不通過'''

                # 測試的用例,一般是所有明顯的邊界用例。

                known_values = ( (1, 'I'), (2, 'II'), (3, 'III'), (4, 'IV'),

                    (5, 'V'), (6, 'VI'), (7, 'VII'), (8, 'VIII'),

                    (9, 'IX'), (10, 'X'), (50, 'L'), (100, 'C'),

                    (500, 'D'), (1000, 'M'), (31, 'XXXI'), (148, 'CXLVIII'),

                    (3888, 'MMMDCCCLXXXVIII'), (3940, 'MMMCMXL'), (3999, 'MMMCMXCIX') )

                for integer, numeral in known_values:

                    result = roman1.to_roman(integer) # 這裏調用真實的方法。如果該方法拋出了異常,則測試被視爲失敗。

                    self.assertEqual(numeral, result) # 檢查兩個值是否相等。如果兩個值不一致,則拋出異常,並且測試失敗。

                    self.assertNotEqual(0, result, '這兩個值不應該相等') # 檢查兩個值是否不相等。

                    self.assertTrue(5 > 0, '5 > 0 都出錯,不是吧')

                    self.assertFalse(5 < 0)

                # 對於每一個失敗的測試用例, unittest 模塊會打印出詳細的跟蹤信息。

                # 如果所有返回值均與已知的期望值一致,則 self.assertEqual 不會拋出任何異常,於是此次測試最終會正常退出,這就意味着 to_roman() 通過此次測試。

                assert 5 > 0 # 爲了更靈活的判斷,可使用 assert


            # 測試異常,讓被測試的方法拋出異常,這裏來驗證異常類型。如果預期的異常沒有拋出,則測試失敗。

            def test_over_value(self):

                '''參數過大或者過小時, to_roman 方法應該拋出異常信息'''

                # assertRaises 方法需要以下參數:你期望的異常、你要測試的方法及傳入給方法的參數。

                #(如果被測試的方法需要多個參數的話,則把所有參數依次傳入 assertRaises, 它會正確地把參數傳遞給被測方法的。)

                self.assertRaises(roman1.OutOfRangeError, roman1.to_roman, 4000)

                # 注意是把 to_roman() 方法作爲參數傳遞;沒有調用被測方法,也不是把被測方法作爲一個字符串名字傳遞進去

                self.assertRaises(roman1.OutOfRangeError, roman1.to_roman, 0)

                self.assertRaises(roman1.OutOfRangeError, roman1.to_roman, -1)


            # 驗證參數類型

            def test_non_integer(self):

                '''如果參數不是 int 類型時, to_roman 方法應該拋出異常'''

                self.assertRaises(roman1.NotIntegerError, roman1.to_roman, 0.5)

                self.assertRaises(roman1.NotIntegerError, roman1.to_roman, 6.0)


        # 在說明每個用例的詳細執行結果之後, unittest 打印出一個簡述來說明“多少用例被執行了”和“測試執行了多長時間”。

        if __name__ == '__main__':

            # main 方法會執行每個測試用例

            unittest.main()



with 關鍵字

    從Python 2.5開始有,需要 from __future__ import with_statement。自python 2.6開始,成爲默認關鍵字。

    with 是一個控制流語句, 跟 if/for/while/try 之類的是一類的,with 可以用來簡化 try finally 代碼,看起來可以比 try finally 更清晰。

    with obj 語句在控制流程進入和離開其後的相關代碼中,允許對象obj管理所發生的事情。

    執行 with obj 語句時,它執行 obj.__enter__() 方法來指示正在進入一個新的上下文。當控制流離開該上下文的時候,它就會執行 obj.__exit__(type, value, traceback)。


    "上下文管理協議"context management protocol: 實現方法是爲一個類定義 __enter__ 和 __exit__ 兩個函數。

    with expresion as variable的執行過程是,首先執行 __enter__ 函數,它的返回值會賦給 as 後面的 variable, 想讓它返回什麼就返回什麼,如果不寫 as variable,返回值會被忽略。

    然後,開始執行 with-block 中的語句,不論成功失敗(比如發生異常、錯誤,設置sys.exit()),在with-block執行完成後,會執行__exit__函數。

    這樣的過程其實等價於:

    try:

        執行 __enter__()

        執行 with_block.

    finally:

        執行 __exit__()


    只不過,現在把一部分代碼封裝成了__enter__函數,清理代碼封裝成__exit__函數。


    例:

        import sys


        class test:

            def __enter__(self):

                print("enter...")

                return 1


            def __exit__(self,*args):

                print("exit...")

                return True


        with test() as t:

            print("t is not the result of test(), it is __enter__ returned")

            print("t is 1, yes, it is {0}".format(t))

            raise NameError("Hi there")

            sys.exit()

            print("Never here")


    注意:

        1) t不是test()的值,test()返回的是"context manager object",是給with用的。t獲得的是__enter__函數的返回值,這是with拿到test()的對象執行之後的結果。t的值是1.

        2) __exit__函數的返回值用來指示with-block部分發生的異常是否要 re-raise ,如果返回 False,則會拋出 with-block 的異常,如果返回 True,則就像什麼都沒發生。


    在Python2.5中, file objec t擁有 __enter__ 和 __exit__ 方法,__enter__ 返回 object 自己,而 __exit__ 則關閉這個文件:

    要打開一個文件,處理它的內容,並且保證關閉它,你就可以簡簡單單地這樣做:


        with open("x.txt") as f:

            data = f.read()

            do something with data


    補充:

        數據庫的連接好像也可以和with一起使用,我在一本書上看到以下內容:

        conn = sqlite.connect("somedb")

        with conn:

            conn.execute("insert into sometable values (?,?)",("foo","bar"))

        在這個例子中,commit()是在所有with數據塊中的語句執行完畢並且沒有錯誤之後自動執行的,如果出現任何的異常,將執行rollback()

        操作,再次提示異常







#####################################################

範例:

1.運行系統命令行

    import os

    os_command = 'echo haha...'

    # 運行命令行,返回運行結果(成功時返回0,失敗返回1或以上的出錯數字)

    result = os.system(os_command)

    if result == 0:

        print('run Successful')

    else:

        print('run FAILED')

    # 注:os.system()函數不推薦使用,它容易引發嚴重的錯誤。(可能是因爲不具備可移植性)


    #os.system(os_command) # 這命令會彈出一個黑乎乎的cmd運行窗口,而且無法獲得輸出

    p = os.popen(os_command) # 捕獲運行的屏幕輸出,以文件類型接收,不再另外彈出窗口

    print(p.read()) # p 是個文件類型,可按文件的操作



2.獲取系統時間

    import time,datetime

    time.sleep(2)  # 時間暫停兩秒

    print(time.strftime('%Y-%m-%d %H:%M:%S')) # 打印如: 2011-04-13 18:30:10

    print(time.strftime('%Y-%m-%d %A %X', time.localtime(time.time()))) # 顯示當前日期; 打印如: 2011-04-13 Wednesday 18:30:10

    print(time.strftime("%Y-%m-%d %A %X", time.localtime())) # 顯示當前日期; 打印如: 2011-04-13 Wednesday 18:30:10

    print(time.time()) # 以浮點數形式返回自Linux新世紀以來經過的秒數; 打印如: 1302687844.7

    print(time.ctime(1150269086.6630149)) #time.ctime([sec]) 把秒數轉換成日期格式,如果不帶參數,則顯示當前的時間。打印如: Wed Apr 13 21:13:11 2011


    # 得到今天的日期

    print(datetime.date.today()) # 打印如: 2011-04-13

    # 得到前一天的日期

    print(datetime.date.today() + datetime.timedelta(days=-1)) # 打印如: 2011-04-12

    print(datetime.date.today() - datetime.timedelta(days=1))  # 打印如: 2011-04-14

    # 得到10天后的時間

    print(datetime.date.today() + datetime.timedelta(days=10)) # 打印如: 2011-04-23

    # 得到10小時後的時間,上面的 days 換成 hours

    print(datetime.datetime.now() + datetime.timedelta(hours=10)) # 打印如: 2011-04-14 04:30:10.189000


    #兩日期相減(也可以大於、小於來比較):

    d1 = datetime.datetime(2005, 2, 16)

    d2 = datetime.datetime(2004, 12, 31)

    print((d1 - d2).days) # 打印: 47


    #運行時間:

    starttime = datetime.datetime.now()

    time.sleep(1) # 暫停1秒

    endtime = datetime.datetime.now()

    print((endtime - starttime).seconds) # 秒, 打印: 1

    print((endtime - starttime).microseconds) # 微秒; 打印: 14000



    日期格式化符號:

    %%: %號本身

    %A: 本地星期(全稱),如:Tuesday   %a: 本地星期(簡稱),如:Tue

    %B: 本地月份(全稱),如:February  %b: 本地月份(簡稱),如:Feb

                                    %c: 本地相應的日期表示和時間表示,如:02/15/11 16:50:57

                                    %d: 月內中的一天(0-31),如:15

    %H: 24進制小時數(0-23)

    %I: 12進制小時數(01-12)

                                    %j: 年內的一天(001-366),如:046

    %M: 分鐘(00-59),如:50           %m: 月份(01-12),如:02

                                    %p: 上下午(本地A.M.或P.M.的等價符),如:PM

    %S: 秒鐘(00-59),如:57

    %X: 本地的時間,如:16:50:57      %x: 本地的日期,如:02/15/11

    %Y: 四位的年(000-9999)          %y: 兩位數的年份表示(00-99)


    %U: 年裏的星期數(00-53)從星期天開始,如:07

    %W: 年裏的星期數(00-53)從星期一開始,如:07

    %w: 星期(0-6),星期天爲星期的開始,如:2 (星期天爲0)

    %Z: 當前時區的名稱,如:中國標準時間

    %z: 當前時區的名稱,如:中國標準時間



3.創建目錄

    import os

    pathDir = r'D:\Work' # 不同系統的目錄寫法有所不同

    if not os.path.exists(pathDir):

        os.mkdir(pathDir) # 創建目錄, os.makedirs(pathDir) 創建多個不存在的目錄

    target = pathDir + os.sep + 'test.txt'

    print(target)

    # 注意os.sep變量的用法, os.sep 是目錄分隔符,這樣寫方便移植。即在Linux、Unix下它是'/',在Windows下它是'\\',而在Mac OS下它是':'。



4.文件操作(讀寫txt文件)

    filePath = 'poem.txt'

    f = open(filePath, 'w') # 以寫的模式打開文件,Python 2.x 需將 open() / io.open() 改成 file()

    for a in range( 0, 10 ):

        s = "%5d %5d\n" % (a, a*a)

        f.write( s ) # 把文本寫入文件

    f.close() # 關閉io流


    f2 = open(filePath) # 沒有提供模式,則默認是讀取,即 'r'

    while True:

        line = f2.readline()

        if len(line) == 0: # 讀取結束

            break

        print(line, end=' ') # 避免print自動換行, 此行Python2.x應該寫:“print line,”

    f2.close() # close the file


    # 刪除文件

    import os

    os.remove(filePath)


    說明:

    一、在pythony 3.0 已經廢棄了 file 類。


    二、pythony 3.0 內置 open() 函數的構造函數是:

    open(file, mode="r", buffering=None, encoding=None, errors=None, newline=None, closefd=True)

    1.mode(模式):

      r: 讀,只能讀文件,如果文件不存在,會發生異常

      w: 寫,只能寫文件,如果文件不存在,創建該文件;如果文件已存在,先清空,再打開文件

      a: 打開供追加

      b: 二進制模式;一般是組合寫法,如: rb 以二進制讀方式打開;wb 以二進制寫方式打開

      t: 文本模式

      +: 打開一個磁盤文件供更新,一般是組合使用,如:

         rb+: 以二進制讀方式打開,可以讀、寫文件,如果文件不存在,會發生異常

         wb+: 以二進制寫方式打開,可以讀、寫文件,如果文件不存在,創建該文件;如果文件已存在,先清空,再打開文件

      u: 通用換行模式

      默認的模式是 rt,即打開供讀取的文本模式。

    2.buffering 關鍵字參數的期望值是以下三個整數中的一個以決定緩衝策略:

      0: 關閉緩衝

      1: 行緩衝

      > 1: 所填的 int 數=緩衝區大小

      默認: 完全緩衝

    3.encoding 默認的編碼方式獨立於平臺。

    4.關閉文件描述符 closefd 可以是 True 或 False 。

      如果是 False,此文件描述符會在文件關閉後保留。若文件名無法奏效的話,那麼必須設爲 True 。


    三、清空文件內容

    f.truncate()

    注意:當以 "r+","rb+","w","wb","wb+"等模式時可以執行該功能,即具有可寫模式時纔可以。


    四、文件的指針定位與查詢

    (1)文件指針:

         文件被打開後,其對象保存在 f 中, 它會記住文件的當前位置,以便於執行讀、寫操作,

         這個位置稱爲文件的指針( 一個從文件頭部開始計算的字節數 long 類型 )。

    (2)文件打開時的位置:

         以"r","r+","rb+" 讀方式, "w","w+","wb+"寫方式 打開的文件,

         一開始,文件指針均指向文件的頭部。

    (3)獲取文件指針的值:

         L = f.tell()

    (4)移動文件的指針

         f.seek(偏移量, 選項) # 偏移量 是 long 或者 int 類型,計算偏移量時注意換行符是2,漢字可能是2或3

         選項 =0 時, 表示將文件指針指向從文件頭部到 "偏移量"字節處。

         選項 =1 時, 表示將文件指針指向從文件的當前位置,向後移動 "偏移量"字節。

         選項 =2 時, 表示將文件指針指向從文件的尾部,,向前移動 "偏移量"字節。


    五、從文件讀取指內容

    1.文本文件(以"rt"方式打開的文件)的讀取

      s = f.readline()

      返回值: s 是字符串,從文件中讀取的一行,含行結束符。

      說明: (1)如果 len(s) = 0 表示已到文件尾(換行符也是有長度的,長度爲2)

            (2)如果是文件的最後一行,有可能沒有行結束符

    2.二進制文件(以"rb"、"rb+"、"wb+" 方式打開的文件)的讀取

      s = f.read(n)

      說明: (1)如果 len( s ) =0 表示已到文件尾

            (2)文件讀取後,文件的指針向後移動 len(s) 字節。

            (3)如果磁道已壞,會發生異常。


    六、向文件寫入一個字符串

      f.write( s )

      參數: s 要寫入的字符串

      說明: (1)文件寫入後,文件的指針向後移動 len(s) 字節。

            (2)如果磁道已壞,或磁盤已滿會發生異常。


    七、常用文件操作參考

      [1.os]

        1.重命名:os.rename(old, new)

        2.刪除:os.remove(file)

        3.列出目錄下的文件:os.listdir(path)

        4.獲取當前工作目錄:os.getcwd()

        5.改變工作目錄:os.chdir(newdir)

        6.創建多級目錄:os.makedirs(r"c:\python\test")

        7.創建單個目錄:os.mkdir("test")

        8.刪除多個目錄:os.removedirs(r"c:\python") #刪除所給路徑最後一個目錄下所有空目錄。

        9.刪除單個目錄:os.rmdir("test")

        10.獲取文件屬性:os.stat(file)

        11.修改文件權限與時間戳:os.chmod(file)

        12.執行操作系統命令:os.system("dir")

        13.啓動新進程:os.exec(), os.execvp()

        14.在後臺執行程序:osspawnv()

        15.終止當前進程:os.exit(), os._exit()

        16.分離文件名:os.path.split(r"c:\python\hello.py") --> ("c:\\python", "hello.py")

        17.分離擴展名:os.path.splitext(r"c:\python\hello.py") --> ("c:\\python\\hello", ".py")

        18.獲取路徑名:os.path.dirname(r"c:\python\hello.py") --> "c:\\python"

        19.獲取文件名:os.path.basename(r"r:\python\hello.py") --> "hello.py"

        20.判斷文件是否存在:os.path.exists(r"c:\python\hello.py") --> True

        21.判斷是否是絕對路徑:os.path.isabs(r".\python\") --> False

        22.判斷是否是目錄:os.path.isdir(r"c:\python") --> True

        23.判斷是否是文件:os.path.isfile(r"c:\python\hello.py") --> True

        24.判斷是否是鏈接文件:os.path.islink(r"c:\python\hello.py") --> False

        25.獲取文件大小:os.path.getsize(filename)

        26.*******:os.ismount("c:\\") --> True

        27.搜索目錄下的所有文件:os.path.walk()

        28.文件的訪問時間 :  os.path.getatime(myfile) # 這裏的時間以秒爲單位,並且從1970年1月1日開始算起

        29.文件的修改時間:  os.path.getmtime(myfile)


      [2.shutil]

        1.複製單個文件:shultil.copy(oldfile, newfle)

        2.複製整個目錄樹:shultil.copytree(r".\setup", r".\backup")

        3.刪除整個目錄樹:shultil.rmtree(r".\backup")


      [3.tempfile]

        1.創建一個唯一的臨時文件:tempfile.mktemp() --> filename

        2.打開臨時文件:tempfile.TemporaryFile()


      [4.StringIO] #cStringIO是StringIO模塊的快速實現模塊

        1.創建內存文件並寫入初始數據:f = StringIO.StringIO("Hello world!")

        2.讀入內存文件數據: print f.read() #或print f.getvalue() --> Hello world!

        3.想內存文件寫入數據:f.write("Good day!")

        4.關閉內存文件:f.close()


      [5.glob]

        1.匹配文件:glob.glob(r"c:\python\*.py")



5.文件操作(遍歷目錄和文件名)

    import os

    import os.path

    rootdir = r"D:\Holemar\1.notes\28.Python\test"

    # os.walk 返回一個三元組,其中parent表示所在目錄, dirnames是所有目錄名字的列表, filenames是所有文件名字的列表

    for parent,dirnames,filenames in os.walk(rootdir):

        # 所在目錄

        print("parent is:" + parent)

        # 遍歷此目錄下的所有目錄(不包含子目錄)

        for dirname in dirnames:

           print(" dirname is:" + dirname)

        # 遍歷此目錄下的所有文件

        for filename in filenames:

           print(" filename with full path:" + os.path.join(parent, filename))


    # 列表顯示出某目錄下的所有文件及目錄(不包括子目錄的內容)

    ls = os.listdir(rootdir)



6.文件操作(分割路徑和文件名)

    import os.path

    #常用函數有三種:分隔路徑,找出文件名,找出盤符(window系統),找出文件的擴展名。

    spath = "d:/test/test.7z"


    # 下面三個分割都返回二元組

    # 分隔目錄和文件名

    p,f = os.path.split(spath)  # 注意二元組的接收

    print("dir is:" + p)    # 打印: d:/test

    print(" file is:" + f)  # 打印: test.7z


    # 分隔盤符和文件名

    drv,left = os.path.splitdrive(spath)

    print(" driver is:" + drv)   # 打印: d:

    print(" left is:" + left)    # 打印: /test/test.7z


    # 分隔文件和擴展名

    f,ext = os.path.splitext(spath)

    print(" f is: " + f)    # 打印: d:/test/test

    print(" ext is:" + ext) # 打印: 7z



7.儲存器

    pickle標準模塊。它可以在一個文件中儲存任何Python對象,之後又可以把它完整無缺地取出來。這被稱爲 持久地 儲存對象。

    在pythony 3.0 已經移除了 cPickle 模塊,可以使用 pickle 模塊代替。


    import pickle as p # 這裏使用 as 簡稱,方便更改模塊時只需改一行代碼

    # import cPickle as p # Python 2.x 有這個模塊(比pickle快1000倍)


    # 將會把資料保存在這個文件裏面

    shoplistfile = 'shoplist.data'


    # 需要保存的資料

    shoplist = ['apple', 'mango', 'carrot', 2, 5]


    # 寫入文件

    f = open(shoplistfile, "wb") # 以二進制寫入,Python2.x時可不用二進制,但3.x必須

    p.dump(shoplist, f) # dump the object to a file

    f.close()


    # 取出資料

    f = open(shoplistfile, "rb") # 以二進制讀取

    storedlist2 = p.load(f)

    print(storedlist2)

    f.close()


    # 刪除文件

    import os

    os.remove(shoplistfile)



8.url編碼操作

    import urllib,sys


    s = '杭州'

    print(urllib.quote(s)) # url 轉碼,打印如: %E6%9D%AD%E5%B7%9E

    print(urllib.unquote('%E6%9D%AD%E5%B7%9E')) # url 解碼,打印如: 杭州


    # 按所用的編碼來轉碼

    print(urllib.quote(s.decode(sys.stdin.encoding).encode('utf8'))) # 打印如: %E6%9D%AD%E5%B7%9E

    print(urllib.quote(s.decode(sys.stdin.encoding).encode('gbk')))  # 打印如: %BA%BC%D6%DD

    print(urllib.quote(s.decode('gbk').encode('utf8'))) # 指定編碼來轉碼

    print(urllib.quote(u'中國'.encode('utf8'))) # unicode編碼的,需encode一下;否則中文會出錯

    # decode就是把其他編碼轉換爲unicode,等同於unicode函數;encode就是把unicode編碼的字符串轉換爲特定編碼。


    # 一些不希望被編碼的url

    print urllib.quote("http://localhost/index.html?id=1") # 打印: http%3A//localhost/index.html%3Fid%3D1

    print urllib.quote("http://localhost/index.html?id=1",":?=/") # 打印: http://localhost/index.html?id=1


    # 查看

    print(u'中國'.__class__) # 打印: <type 'unicode'>

    print('中國'.__class__)  # 打印: <type 'str'>



9.數據庫連接

    cx_Oracle : 是一個用來連接並操作 Oracle 數據庫的 Python 擴展模塊, 支持包括 Oracle 9.2 10.2 以及 11.1 等版本。

      安裝:

        需先oracle安裝客戶端,並配置環境變量:

            ORACLE_HOME=D:\Oracle\Ora81

          PATH=D:\Oracle\Ora81\bin;(其他path的地址)

        下載 cx_Oracle 安裝包: http://www.python.net/crew/atuining/cx_Oracle/


      Oracle 示例:

        import cx_Oracle

        print(cx_Oracle.version) # 打印出版本信息

        # 建立連接, 3種不同寫法

        conn = cx_Oracle.connect('username/pwssword@localhost:1521/db_name') # 參數連寫

        conn = cx_Oracle.connect('username', 'pwssword', 'ip_address:1521/db_name') # 分開3個參數寫

        dsn_tns = cx_Oracle.makedsn('localhost', 1521, 'db_name')

        conn = cx_Oracle.connect('username', 'pwssword', dsn_tns) # 分開5個參數寫



    MySQLdb   : MySQL 數據庫的 Python 擴展模塊

        import MySQLdb

                下載地址(tar安裝包): http://sourceforge.net/projects/mysql-python

                 (exe安裝文件) http://www.lfd.uci.edu/~gohlke/pythonlibs/


    mongodb:

        下載數據庫安裝文件: http://www.mongodb.org/downloads

        import pymongo



    其他數據庫:

    postgresql PostgreSQL psycopg version 1.x, http://initd.org/projects/psycopg1

    postgresql_psycopg2 PostgreSQL psycopg version 2.x, http://initd.org/projects/psycopg2

    sqlite3 SQLite No adapter needed if using Python 2.5+ Otherwise, pysqlite, http://initd.org/tracker/pysqlite

    ado_mssql Microsoft SQL Server adodbapi version 2.0.1+, http://adodbapi.sourceforge.net/


     MySQL 示例:

        # 0. 導入模塊(如果導入出錯,說明安裝驅動不成功)

        import MySQLdb


        # 1. 數據庫聯結,默認host爲本機, port爲3306(各數據庫的連接寫法有所不同)

        conn = MySQLdb.connect(host="localhost", port=3306, user="root", passwd="root", db="testdb")

        # conn = MySQLdb.Connection(host="localhost", port=3306, user="root", passwd="root", db="testdb") # 與上句一樣


        # 2. 選擇數據庫(如果前面還沒有選擇數據庫的話)

        conn.select_db('database name')


        # 3. 獲得cursor

        cursor = conn.cursor()


        # 4.1 執行SQL,查詢和增刪改都這樣寫; 查詢返回查詢結果的行數,增刪改返回影響的行數

        cursor.execute("SELECT * FROM tb_member")


        # 4.1.1. cursor位置設定及讀取結果(僅查詢時可這樣用)

        # cursor.scroll(int, mode) # mode可爲相對位置或者絕對位置,分別爲relative和absolute。

        cursor.scroll(0)


        # 4.1.2. Fetch 及 獲取結果(每次Fetch,結果集都會下移,下次獲取的是剩下的結果集,除非再 cursor.scroll() 移動結果集)

        print(cursor.fetchone()) # 獲取對應位置的資料,返回一個一維元組,打印如:(1L, 'stu1', 'm')

        print(cursor.fetchall()) # 返回結果是個二維元組(所有結果) 打印如:((1L, 'stu1', 'm'), (2L, 'stu2', 'f'))


        # 4.2 execute SQL, 返回影響的行數

        rows = cursor.execute("delete from tb_member where memid=2")

        print(rows) # 返回影響的行數(整數類型), 打印如:1


        # 5. 關閉連接

        cursor.close()

        conn.close()



10.需注意的默認參數

    # 默認參數: 如果調用的時候沒指定,那它會是函數定義時的引用;

    # 因此,默認參數建議使用基本類型;如果不是基本類型,建議寫 None,然後在函數裏面設默認值


    ##### 範例1,默認參數如果是 []、{} ,將會影響全局 ########

    def t1(a, b = []):

        b.append(a)

        print('%s  %s' % (id(b), b))


    t1(1)       # 打印: 12523400  [1]

    t1(2)       # 打印: 12523400  [1, 2]

    t1(3, b=[]) # 打印: 12545000  [3]


    def t2(a, b = {}):

        b[len(b)] = a

        print('%s  %s' % (id(b), b))


    t2(1)       # 打印: 12540928  {0: 1}

    t2(2)       # 打印: 12540928  {0: 1, 1: 2}

    t2(3, b={}) # 打印: 11547392  {0: 3}



    ##### 範例2,如果默認的是其它的函數調用,同樣原理,默認值只是函數定義時的引用,後面不再改變 ########

    import time

    def cc(a,b = time.time()):print('%s  %s' % (a,b))


    cc(1)      # 打印: 1 1306501851.48

    cc(1,b=2)  # 打印: 1 2

    cc(2)      # 打印: 2 1306501851.48



    ##### 範例3,只是爲了更好的理解上述所講 ########

    def aa():

        print('aa...')

        return []


    # 只在函數定義時,執行被調用的 aa(), 後面不再執行

    def bb(a,b = aa()):

        b.append(1)

        print('%s  %s' % (id(b), b))


    bb(1) # 打印: 12542840  [1]

    bb(2) # 打印: 12542840  [1, 1]


    ################################################

    # 範例4, 爲避免上面的出錯,正確的寫法是這樣的:

    def t1(a, b = None):

        b = b or []

        b.append(a)

        print('%s  %s' % (id(b), b))


    def t2(a, b = None):

        b = b or {}

        b[len(b)] = a

        print('%s  %s' % (id(b), b))


    import time

    def cc(a, b = None):

        b = b or time.time()

        print('%s  %s' % (a,b))



11. 隨機數

    from random import randint # 產生隨機整數

    for i in xrange(100):

        print( randint(10, 90) ) # 產生 10~90 的隨機整數



12. 條件參數列表

    在實際開發中,我們會遇到如下一種需求:

    1. 默認條件有 (a, b, c, d ...),總之很多。

    2. 調用者可以傳遞 (b = False, c = False) 來提供 "非" 條件,其他默認爲 True。

    3. 或者傳遞 (b = True, c = True),其他默認爲 False。

    4. 還可以用 (all = True, ...) 來明確指定默認值。


    def test(**on):

        # 全部條件列表

        accept_args = ("a", "b", "c", "d", "e")


        # 默認條件

        default = on.pop("all", None)


        # 如果沒有顯式指明默認條件,則檢查參數列:

        #   1. 如果有任何一個 True 條件則默認值爲 False。

        #   2. 如果全部爲 False,則默認值爲 True。

        if default is None: default = not(True in on.values())


        # 使用 setdefault 補全參數字典

        for k in accept_args: on.setdefault(k, default)


        return on



    print test(b = False, e = False)                # 顯示:{'a': True, 'c': True, 'b': False, 'e': False, 'd': True}

    print test(c = True)                            # 顯示:{'a': False, 'c': True, 'b': False, 'e': False, 'd': False}

    print test(a = True, e = False)                 # 顯示:{'a': True, 'c': False, 'b': False, 'e': False, 'd': False}

    print test(all = True, c = False, e = True)     # 顯示:{'a': True, 'c': False, 'b': True, 'e': True, 'd': True}

    print test(all = True, c = False, e = False)    # 顯示:{'a': True, 'c': False, 'b': True, 'e': False, 'd': True}

    print test(all = False, c = True, e = True)     # 顯示:{'a': False, 'c': True, 'b': False, 'e': True, 'd': False}



13. 斷點調試

    import pdb; pdb.set_trace() # 運行到這語句,會出現斷點


    輸入命令:

    命令的詳細幫助: h

    查看代碼上下文, l(小寫L)

    監視變量: p 變量名

    單步執行: n

    加入斷點: b 行號

    跳出斷點: c

    執行到函數返回前: r



14. 修改註冊表(使用 _winreg, python3.x是 winreg 模塊, 內置模塊)

    官方的參考文檔:

    http://docs.python.org/library/_winreg.html

    http://www.python.org/doc/2.6.2/library/_winreg.html


    1.  讀取

        讀取用的方法是OpenKey方法:打開特定的key

        hkey = _winreg.OpenKey(key,sub_key,res=0,sam=KEY_READ)

        _winreg.CloseKey(hkey) # 關閉之前打開的,如果不關閉則在對象被銷燬時關閉


        例子:

        import _winreg

        key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, r"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\{0E184877-D910-4877-B 4C2-04F487B6DBB7}")


        #獲取該鍵的所有鍵值,遍歷枚舉

        try:

            i=0

            while 1:

                # EnumValue方法用來枚舉鍵值,EnumKey用來枚舉子鍵

                print _winreg.EnumValue(key,i) # 打印: (name,value,type)

                i+=1

        except WindowsError:

            print


        #假如知道鍵名,也可以直接取值

        print _winreg.QueryValueEx(key,"ExplorerStartupTraceRecorded") # 打印: (value,type)


    2.  創建 修改註冊表

        創建key:_winreg.CreateKey(key,sub_key)

        創建key:_winreg.CreateKeyEx(key, sub_key[, res[, sam]])

        刪除key: _winreg.DeleteKey(key,sub_key)

        刪除鍵值: _winreg.DeleteValue(key,value)

        給新建的key賦值: _winreg.SetValue(key,sub_key,type,value)


        例子:

        import _winreg


        key=_winreg.OpenKey(_winreg.HKEY_CURRENT_USER,r"Software\Microsoft\Windows\CurrentVersion\Explorer")

        # 刪除鍵(沒有時會報錯)

        _winreg.DeleteKey(key, "Advanced")

        # 刪除鍵值(沒有時會報錯)

        _winreg.DeleteValue(key, "IconUnderline")

        # 創建新的項

        newKey = _winreg.CreateKey(key,"MyNewkey")

        # 給新創建的項,添加鍵值(會多一個項:ValueName, 默認的值是ValueContent)

        _winreg.SetValue(newKey,"ValueName", _winreg.REG_SZ, "ValueContent")


    3.  訪問遠程註冊表

        # 第二參數必須是HKEY_CURRENT_USER、HKEY_LOCAL_MACHINE等預先定義好的值,拿到返回的key後就可以進行操作了

        key = _winreg.ConnectRegisty("IP地址或者機器名", _winreg.HKEY_CURRENT_USER)


    實例: 修改IE代理服務器

        import _winreg # python3 則寫 winreg

        import ctypes


        #proxy = "127.0.0.1:8000"

        proxy = "http=127.0.0.1:8580;https=127.0.0.1:8580;ftp=127.0.0.1:8580" # 代理服務器地址

        ProxyOverride = '<local>;192.168.*;127.*' # 不使用代理服務器的IP段,或者域名段,可以用*代表任意長字符串,如: 192.168.*

        root = _winreg.HKEY_CURRENT_USER

        proxy_path = r"Software\Microsoft\Windows\CurrentVersion\Internet Settings"


        hKey = _winreg.OpenKey(root, proxy_path)

        # value 是代理是否開啓的標誌,0表示不使用代理,1表示使用

        value, type = _winreg.QueryValueEx(hKey, "ProxyEnable")

        if value: # value 爲 0 時

            print("原本已使用代理")

        else:

            print("原本還沒使用代理")


        # 修改代理設置

        hKey = _winreg.CreateKey(root, proxy_path)

        _winreg.SetValueEx(hKey, "ProxyEnable", 0, _winreg.REG_DWORD, 0) # 最後的參數是代理的開關,0爲關閉代理,1爲開啓

        _winreg.SetValueEx(hKey, "ProxyServer", 0, _winreg.REG_SZ, proxy)

        # 不使用代理服務器的IP段,或者域名段,可以用*代表任意長字符串

        _winreg.SetValueEx(hKey, "ProxyOverride", 0, _winreg.REG_SZ, ProxyOverride)

        _winreg.SetValueEx(hKey, "MigrateProxy", 0, _winreg.REG_DWORD, 1) # 是否所有協議使用相同代理服務器: 0爲否,1爲是

        # 最後,關閉註冊表連接

        _winreg.CloseKey(hKey)


        # IE Reload註冊表的信息, 因爲修改註冊表之後, ie不會馬上生效, 需要這一段; 但在win7系統似乎有點問題

        INTERNET_OPTION_REFRESH = 37

        INTERNET_OPTION_SETTINGS_CHANGED = 39

        internet_set_option = ctypes.windll.Wininet.InternetSetOptionW

        internet_set_option(0, INTERNET_OPTION_REFRESH, 0, 0)

        internet_set_option(0, INTERNET_OPTION_SETTINGS_CHANGED, 0, 0)



14. 修改註冊表(使用 win32api, win32con 模塊,需安裝)

    1.  下載和安裝模塊: http://starship.python.net/crew/mhammond/downloads/

        下載像“pywin32-212.6.win32-py2.6.exe”來安裝


    2.  註冊表基本項

            項名                      描述

        HKEY_CLASSES_ROOT          是HKEY_LOCAL_MACHINE\Software 的子項,保存打開文件所對應的應用程序信息

        HKEY_CURRENT_USER          是HKEY_USERS的子項,保存當前用戶的配置信息

        HKEY_LOCAL_MACHINE         保存計算機的配置信息,針對所有用戶

        HKEY_USERS                 保存計算機上的所有以活動方式加載的用戶配置文件

        HKEY_CURRENT_CONFIG        保存計算機的硬件配置文件信息


    3. 打開註冊表

        win32api.RegOpenKey(key, subkey, reserved, sam)

        win32api.RegOpenKeyEx(key, subkey, reserved, sam)

        兩個函數的參數用法一樣。參數含義如下:

          Key:必須爲表1中列出的項。

          SubKey:要打開的子項。

          Reserved:必須爲0。

          Sam:對打開的子項進行的操作,包括 win32con.KEY_ALL_ACCESS、 win32con.KEY_READ、 win32con.KEY_WRITE 等


    4.  關閉註冊表

        win32api.RegCloseKey(key)

        其參數只有一個,其含義如下:

          Key:已經打開的註冊表項的句柄。


        如:

        key = win32api.RegOpenKey(win32con.HKEY_CURRENT_USER, 'Software', 0, win32con.KEY_READ)

        print key # 顯示: <PyHKEY at 7670448 (220)>

        win32api.RegCloseKey(key)

        print key # 顯示: <PyHKEY at 7670448 (0)>


    5.  讀取項值

        win32api.RegQueryValue(key,subKey) # 讀取項的默認值;其參數含義如下:

            Key:已打開的註冊表項的句柄。

            subKey:要操作的子項。


        win32api.RegQueryValueEx(key,valueName) # 讀取某一項值;其參數含義如下:

            Key:已經打開的註冊表項的句柄。

            valueName:要讀取的項值名稱。


        win32api.RegQueryInfoKey(key)  # RegQueryInfoKey函數查詢項的基本信息; 返回項的子項數目、項值數目,以及最後一次修改時間


      如:

        import win32api

        import win32con


        # 打開“HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer”項

        key = win32api.RegOpenKey(win32con.HKEY_LOCAL_MACHINE,'SOFTWARE\\Microsoft\\Internet Explorer',0, win32con.KEY_ALL_ACCESS)


        # 讀取項的默認值''

        # 輸出爲空,表示其默認值未設置

        print win32api.RegQueryValue(key,'')


        #讀取項值名稱爲Version的項值數據,也就是Internet Explorer的版本

        print win32api.RegQueryValueEx(key,'Version') # 顯示如:('6.0.2900.2180', 1)

        print win32api.RegQueryInfoKey(key)  # 查詢項的基本信息,顯示如:(26, 7, 128178812229687500L)


    6.  設置項值

        win32api.RegSetValue(key,subKey,type,value) # 設置項的默認值

            Key:已經打開的項的句柄。

            subKey:所要設置的子項。

            Type:項值的類型,必須爲 win32con.REG_SZ。

            Value:項值數據,爲字符串。


        win32api.RegSetValueEx(key,valueName,reserved,type,value) # 要修改或重新設置註冊表某一項的項值。如果項值存在,則修改該項值,如果不存在,則添加該項值。

            Key:要設置的項的句柄。

            valueName:要設置的項值名稱。

            Reserved:保留,可以設爲0。

            Type:項值的類型。

            Value:所要設置的值。


      如:

        # 將“HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer”的默認值設爲python

        win32api.RegSetValue(key,'',win32con.REG_SZ,'python')

        # 修改“Version”的值

        win32api.RegSetValueEx(key,'Version',0,win32con.REG_SZ,'7.0.2900.2180')


    7.  添加、刪除項

        win32api.RegCreateKey(key,subKey) # 向註冊表中添加項

        win32api.RegDeleteKey(key,subKey) # 刪除註冊表中的項

        兩個函數的參數用法一樣。參數含義如下:

            Key:已經打開的註冊表項的句柄。

            subKey:所要操作(添加或刪除)的子項。


      如:

        # 向“HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer”添加子項“Python”

        win32api.RegCreateKey(key,'Python') # 此時會多一個“HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\\Python”

        # 刪除剛纔創建的子項“Python”

        win32api.RegDeleteKey(key,'Python') # 沒有此項時,會拋出錯誤


    實例: 修改IE代理服務器

        # 注意,新設置好的代理服務器,不會對之前已經開啓的IE起效,只對之後開啓的IE有效。

        import win32api

        import win32con

        # 打開“HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings”項;代理設置在註冊表中的位置

        key = win32api.RegOpenKey(win32con.HKEY_CURRENT_USER, r'Software\Microsoft\Windows\CurrentVersion\Internet Settings', 0, win32con.KEY_ALL_ACCESS)

        # "ProxyEnable"=dword:00000001       ;是否啓用代理服務器,dword:00000001表示開啓,dword:00000000表示失效

        win32api.RegSetValueEx(key, 'ProxyEnable', 0, win32con.REG_DWORD, 1)

        # "ProxyServer"="192.168.0.1:8088"   ;代理服務器的地址和端口

        win32api.RegSetValueEx(key, 'ProxyServer', 0, win32con.REG_SZ, '127.0.0.1:8000')

        # "ProxyOverride"="192.168.*"        ;不使用代理服務器的IP段,或者域名段,可以用*代表任意長字符串

        win32api.RegSetValueEx(key, 'ProxyOverride', 0, win32con.REG_SZ, '192.168.*')


        # 想把IE代理去掉,如:

        win32api.RegSetValueEx(key, 'ProxyEnable', 0, win32con.REG_DWORD, 0)

        # 最後,關閉註冊表連接

        win32api.RegCloseKey(key)



15. 多線程

  1、函數式:調用thread模塊中的start_new_thread()函數來產生新線程。如:

    import time

    import thread


    def timer(no, interval):

        cnt = 0

        while cnt<10:

            print 'Thread:(%d) Time:%s\n'%(no, time.ctime())

            #time.sleep(interval)

            cnt += 1

        # 線程的結束可以等待線程自然結束,也可以在線程函數中調用 thread.exit() 或 thread.exit_thread() 方法。

        thread.exit_thread()


    def test():

        # 用 thread.start_new_thread() 來創建兩個線程

        # thread.start_new_thread(function, args[, kwargs]) 的第一個參數是線程函數;第二個參數是傳遞給線程函數的參數,它必須是tuple類型;kwargs是可選參數

        thread1 = thread.start_new_thread(timer, (1,1))

        thread2 = thread.start_new_thread(timer, (2,2))

        print '開始運行\n'

        time.sleep(1) # 此處如果不睡的話會報錯,因爲主進程結束而子線程沒結束

        print '運行結束'


    if __name__=='__main__':

        test()



  2、創建 threading.Thread 的子類來包裝一個線程對象,如下例:

    import threading

    import time


    class timer(threading.Thread): #The timer class is derived from the class threading.Thread

        def __init__(self, num, interval):

            threading.Thread.__init__(self)

            self.thread_num = num

            self.interval = interval

            self.thread_stop = False


        def run(self): #Overwrite run() method, put what you want the thread do here

            while not self.thread_stop:

                print 'Thread Object(%d), Time:%s\n' %(self.thread_num, time.time())

                time.sleep(self.interval)


        def stop(self):

            self.thread_stop = True



    def test():

        thread1 = timer(1, 1)

        thread2 = timer(2, 2)

        thread1.start()

        thread2.start()

        time.sleep(10)

        thread1.stop()

        thread2.stop()

        return


    if __name__ == '__main__':

        test()



    threading.Thread類的使用:

    1,在自己的線程類的__init__裏調用threading.Thread.__init__(self, name = threadname) # threadname 爲線程的名字

    2, run(),通常需要重寫,編寫代碼實現做需要的功能。

    3,getName(),獲得線程對象名稱

    4,setName(),設置線程對象名稱

    5,start(),啓動線程

    6,jion(timeout=None),等待另一線程結束後再運行。如果給出timeout,則最多阻塞timeout秒

    7,setDaemon(bool),設置子線程是否隨主線程一起結束,必須在start()之前調用。默認爲False。

    8,isDaemon(),判斷線程是否隨主線程一起結束。

    9,isAlive(),檢查線程是否在運行中。

       此外threading模塊本身也提供了很多方法和其他的類,可以幫助我們更好的使用和管理線程。可以參看http://www.python.org/doc/2.5.2/lib/module-threading.html。


http://www.cnblogs.com/tqsummer/archive/2011/01/25/1944771.html

http://blog.sina.com.cn/s/blog_4b5039210100esc1.html

http://sm4llb0y.blog.163.com/blog/static/18912397200981594357140/



16. 多進程 (從 2.6 起增加了子進程級別的並行開發支持 —— multiprocessing)

    #!/usr/bin/env python

    # -*- coding:utf-8 -*-


    import os, time

    from multiprocessing import *


    def test(x):

        print current_process().pid, x

        #time.sleep(1)


    if __name__ == "__main__":

        print "main:", os.getpid()

        p = Pool(5)

        p.map(test, range(13)) # 啓動13個子進程

        time.sleep(1)


  1. Process

    我們先從最根本的 Process 入手,看看是如何啓動子進程完成並行計算的。上面的 Pool 不過是創建多個 Process,然後將數據(args)提交給多個子進程完成而已。


    import os, time

    from multiprocessing import *


    def test(x):

        print current_process().pid, x

        time.sleep(1)


    if __name__ == "__main__":

        print "main:", os.getpid()

        p = Process(target = test, args = [100])

        p.start()

        p.join()



17. 進程監視(windows)

    # 定期監視某進程是否存在,不存在則執行

    import os,time


    def __Is_Process_Running(imagename):

        '''

           功能:檢查進程是否存在

           返回:返回有多少個這進程名的程序在運行,返回0則程序不在運行

        '''

        p = os.popen('tasklist /FI "IMAGENAME eq %s"' % imagename) # 利用 windows 批處理的 tasklist 命令

        return p.read().count(imagename) # p 是個文件類型,可按文件的操作


    def test():

        '''

           功能:定期地監視測進程是否還在運行,不再運行時執行指定代碼

        '''

        while True:

            time.sleep(10)

            pid = __Is_Process_Running('barfoo.exe')

            if pid <= 0:

                # code .....

                break


    if __name__ == "__main__":

        test()



18. 程序退出時執行

    # 註冊 atexit 函數來解決

    # 如果中途關閉運行窗口,無法調用結束事件

    import threading

    import time

    import atexit


    def clean():

        print "clean temp data..."


    def test():

        for i in range(10):

            name = threading.currentThread().name

            print name, i

            # time.sleep(1)


    if __name__ == "__main__":

        atexit.register(clean) # 註冊程序結束時執行的函數

        threading.Thread(target = test).start()

        time.sleep(1)


        exit(4) # quit() 和 exit() 會等待所有前臺線程退出,同時會調用退出函數。

        import sys; sys.exit(4) # 和 exit / quit 作用基本相同。等待前臺線程退出,調用退出函數。

        import os; os._exit(4) # os._exit() 通過系統調用來終止進程的,所有線程和退出函數統統滾蛋。


        time.sleep(1)

        print "Ho ..."


    import subprocess



18. 程序退出時執行

    # 通過 subprocess.Popen 函數來解決;但會發生問題,不知道內部是什麼原因

    import subprocess

    proc = subprocess.Popen("python test.py")

    proc.wait()


    # 前面的程序結束後,才繼續執行下面的代碼

    test_file = open('test.txt', 'wb')

    test_file.write('hello') # 這裏的寫入偶爾會出問題,不知道原因

    test_file.close()



18. 程序退出時執行

    import os


    # 運行另外一個進程

    proxy_server = os.popen('cmd.exe /c start "" barfoo_proxy.exe')

    # 等待這個進程結束(其實是讀取程序的輸出,但程序如果一直不停止的話,就一直阻塞),再往下執行

    proxy_server.read()


    # 前面的程序結束後,才繼續執行下面的代碼

    test_file = open('test.txt', 'wb')

    test_file.write('hello')

    test_file.close()



19. 殺掉進程(windows)

    def kill(pid):

        """ kill process by pid for windows """

        kill_command = "taskkill /F /T /pid %s" % pid

        os.system(kill_command)



20. 反射(自省)

    dir([obj]):                 調用這個方法將返回包含obj大多數屬性名的列表(會有一些特殊的屬性不包含在內)。obj的默認值是當前的模塊對象。

    hasattr(obj, attr):         這個方法用於檢查obj是否有一個名爲attr的值的屬性,返回一個布爾值。

    getattr(obj, attr):         調用這個方法將返回obj中名爲attr的屬性對象,或者名爲attr的函數, 例如如果attr爲'bar',則返回obj.bar。

    setattr(obj, attr, val):    調用這個方法將給obj的名爲attr的值的屬性賦值爲val。例如如果attr爲'bar',則相當於obj.bar = val。

    callable(obj):              如果傳入的參數是可以調用的對象或函數,則返回 True, 否則返回 False 。


    例:

        # 測試類

        class Cat(object):

            def __init__(self, name='kitty'):

                self.name = name

            def sayHi(self): #  實例方法,sayHi指向這個方法對象,使用類或實例.sayHi訪問

                print(self.name + 'says Hi!') # 訪問名爲name的字段,使用實例.name訪問



        cat = Cat('kitty2')

        print(dir(cat)) # 獲取實例的屬性名,以列表形式返回

        if hasattr(cat, 'name'): # 檢查實例是否有這個屬性

            setattr(cat, 'name', 'tiger') # 相當於: cat.name = 'tiger'

        print(getattr(cat, 'name')) # 相當於: print(cat.name)


        getattr(cat, 'sayHi')() # 相當於: cat.sayHi()



        # 下面這段代碼列出對象的所有函數或可調用的對象:

        methodList = [method for method in dir(cat) if callable(getattr(cat, method))]


        # globals() 返回一個map,這個map的key是全局範圍內對象的名字,value是該對象的實例。

        globals().get('Cat')()  # 相當於執行: Cat();   注意,這用法需要導入相應的類,如果不導入,則會拋出異常。


        # 解決不能直接導入的問題,使用動態導入

        module = __import__('test_lib') # 導入模組, 多重的導入照樣使用點運算符, 如: module = __import__('test_lib.test')

        parser = getattr(module, 'test_fun')  # 獲取模組裏面的對象,可以是函數或者屬性或者類

        test_attr = getattr(module, 'test_attr')

        parser()  # 獲取模組裏面的對象如果是函數或者類,可直接調用

        print(test_attr) # 調用模組裏面的屬性

        print(dir(module)) # 列表模組裏面的所有內容



    http://www.cnblogs.com/huxi/archive/2011/01/02/1924317.html

    http://blog.csdn.net/lokibalder/article/details/3459722



21. @符號修飾函數(有的語言稱爲:註釋)

    python 2.4以後,增加了 @符號修飾函數 對函數進行修飾, python3.0/2.6又增加了對類的修飾。

    修飾符必須出現在函數定義前一行,不允許和函數定義在同一行。也就是說 @A def f(): 是非法的。


        class Person:

            def sayHi(self):  # self參數必須寫,正常函數的寫法

                print('Hello, how are you?')


            @staticmethod # 申明此方法是一個靜態方法,外部可以直接調用

            def tt(a): # 靜態方法,第一個參數不需要用 self

                print(a)


            def ff(self):

                self.sayHi() # 正常方法的調用

                self.tt('dd') # 靜態方法的調用


        p = Person()

        p.ff() # 正常方法的調用: self參數不需賦值, 必須先 new 出一個類纔可以用

        Person.tt('a', 'b') # 可以直接調用



    # 下面的效果類似於: dec1(dec2(test(arg)))

    @dec1

    @dec2

    def test1(arg):

        print(arg)


    #修飾函數還可以帶參數, 效果類似於: dec1(arg1,arg2)(test(arg))

    @dec1(arg1,arg2)

    def test2(arg):

        pass



    範例:

    def accepts(*types):

        def check_accepts(f):

            assert len(types) == f.func_code.co_argcount

            def new_f(*args, **kwds):

                for (a, t) in zip(args, types):

                    assert isinstance(a, t), "arg %r does not match %s" % (a,t)

                return f(*args, **kwds)

            new_f.func_name = f.func_name

            return new_f

        return check_accepts


    def returns(rtype):

        def check_returns(f):

            def new_f(*args, **kwds):

                result = f(*args, **kwds)

                assert isinstance(result, rtype), "return value %r does not match %s" % (result,rtype)

                return result

            new_f.func_name = f.func_name

            return new_f

        return check_returns


    @accepts(int, (int,float))

    @returns((int,float))

    def func(arg1, arg2):

        return arg1 * arg2



http://www.python.org/dev/peps/pep-0318/

http://blog.csdn.net/pythoner/article/details/2823260



22. 垃圾回收

    import gc

    gc.collect() # 顯示調用垃圾回收


    gc.disable() # 關閉垃圾回收,當程序需要大量內存時可調用這語句,避免頻繁的垃圾回收而影響效率

    gc.enable()  # 開啓垃圾回收



23. 利用 Python 搭建一個簡單的 Web 服務器,快速實現局域網內文件共享。

    1. cd 到準備做服務器根目錄的路徑下(這目錄下的文件將會被共享)

    2. 運行命令:

       python -m Web服務器模塊[端口號,默認8000]

       這裏的“Web服務器模塊”有如下三種:

            BaseHTTPServer: 提供基本的Web服務和處理器類,分別是HTTPServer和BaseHTTPRequestHandler。

            SimpleHTTPServer: 包含執行GET和HEAD請求的SimpleHTTPRequestHandler類。

            CGIHTTPServer: 包含處理POST請求和執行CGIHTTPRequestHandler類。


       運行如: python -m SimpleHTTPServer 8080


    3. 可以在瀏覽器中訪問:

       http://$HOSTNAME:端口號/路徑









#############################################################

################## 內置變量 #################################


__all__

    這是一個字符串列表,定義在一個模塊出口時使用 from <module> import * 將可以引用到什麼變量,但對 import <module> 沒有影響。

    沒有定義此語句,則 import * 默認的行爲是導入所有的符號不以下劃線開始的對象。


    例如:

    a1.py 的內容如下:

    __all__=['b','c']

    a='aaa'

    b='bbb'

    c='ccc'


    b1.py 的內容如下:

    import a1

    from a1 import *

    print a1.a # 正常打印

    print b # 正常打印

    print a # 報錯了,變量未定義



__call__

    類的調用

    只要定義類的時候,實現 __call__ 函數,這個類型就成爲可調用的。

    換句話說,我們可以把這個類型的對象當作函數來使用,相當於 重載了括號運算符。



__del__

    del 類名 # 調用對象的 __del__ 方法



__doc__

    docstring


    例:

    print(Person.__doc__) # 打印類的docstring

    print(Person.func_name.__doc__) # 打印類的方法的docstring



__file__

    當前代碼所在的Python模塊的文件名。


    例:

    import os, sys

    print( os.path.dirname(os.path.realpath(__file__)) ) # 獲取當前目錄

    print( os.path.dirname(os.path.dirname(os.path.realpath(__file__))) ) # 獲取上一層目錄

    print( os.path.dirname(os.path.abspath(sys.argv[0])) ) # 獲取當前目錄, sys.argv[0] 與 __file__ 一樣顯示當前文件名

    print( os.getcwd() ) # 獲取當前目錄

    print( os.path.abspath(os.curdir) ) # 獲取當前目錄

    print( os.path.abspath( '. ') ) # 獲取當前目錄, 打印會加上點號,如: /home/holemar/project/ppf_web/.



__init__

    類的構造方法


    例:

    class Human(object):

        def __init__(self, name):

            print(name)


    class Person(Human): # Person 類繼承 Human 類

        def __init__(self, name):

            self.name = name # 對象的變量,每個對象獨立的

            super(Person, self).__init__(name)  # 調用父類的 __init__ 方法,但這樣的調用要求父類必須繼承 object 類,或者繼承其它的類

            Human.__init__(self, "province") # 這樣調用父類的 __init__ 方法也可以



__name__

    每個Python模塊都有它的__name__,如果它是'__main__',這說明這個模塊被用戶單獨運行,我們可以進行相應的恰當操作。


    例:

    if __name__ == '__main__':

        print('This program is being run by itself')

    else:

        print('I am being imported from another module')



__version__

    版本信息


    例如:

    __version__ = '2.6.26'

    print( tuple(int(i) for i in __version__.split('.')) ) # 打印: (2, 6, 26)

    print( float(__version__) ) # 報錯



運算符,如大於、小於、等於、加減乘除, 等等

    class Field(object):

        def __init__(self, value):

            self.value = value


        # 小於:  x < y, y > x

        def __lt__(self, value):

            print('__lt__ 被調用啦...')

            return self.value < value

        # 小於等於:  x <= y, y >= x

        def __le__(self, value):

            return self.value <= value

        # x > y, y < x

        def __gt__(self, value):

            return self.value > value

        # x >= y, y <= x

        def __ge__(self, value):

            return self.value >= value


        # 等於: x == y

        def __eq__(self, value):

            return self.value == value

        # 不等於:  x != y, x <> y

        def __ne__(self, value):

            return self.value != value


        # 加:  x + y

        def __add__(self, value):

            return str(self.value) + ' + ' + str(value)

        # y + x

        def __radd__(self, value):

            return str(value) + ' + ' + str(self.value)


        # 減: x - y

        def __sub__(self, value):

            return str(self.value) + ' - ' + str(value)

        # y - x

        def __rsub__(self, value):

            return str(value) + ' - ' + str(self.value)


        # 乘: x * y

        def __mul__(self, value):

            return str(self.value) + ' × ' + str(value)

        # y * x

        def __rmul__(self, value):

            return str(value) + ' × ' + str(self.value)


        # 除: x / y

        def __div__(self, value):

            return str(self.value) + ' ÷ ' + str(value)

        # y / x

        def __rdiv__(self, value):

            return str(value) + ' ÷ ' + str(self.value)

        # 整除: x // y

        def __floordiv__(self, value):

            return str(self.value) + ' // ' + str(value)

        # y // x

        def __rfloordiv__(self, value):

            return str(value) + ' // ' + str(self.value)

        # python2裏面不知道怎麼調用這個函數,但python3沒有了 __div__,除的時候直接調用此函數

        def __truediv__(self, value):

            return str(self.value) + ' / ' + str(value)

        def __rtruediv__(self, value):

            return str(value) + ' / ' + str(self.value)


        # 單元運算符

        # ~x

        def __invert__(self):

            return '~' + str(self.value)

        # -x

        def __neg__(self):

            return '-' + str(self.value)

        # +x

        def __pos__(self):

            return '+' + str(self.value)


        # x[y]

        def __getitem__(self, value):

            return 'this[' + str(value) + ']'

        # x[y] = z

        def __setitem__(self, key, value)

            self[key] = value

        # del x[y]

        def __delitem__(self, value):

            del self[value]

        # x[y:z]

        def __index__(self, y, z):

            return self[y:z]

        # 遍歷

        def __iter__(self):

            pass

        # y in x

        def __contains__(self, value): # in 判斷,只能返回 True / False

            return False


        # x.name

        #def __getattribute__(self, value): # 覆蓋此方法後,調用 self.value 會引起死循環

        #    return 'this.' + str(value)



        # 被特定函數調用時

        # len(x) ,返回值必須大於或等於0

        def __len__(self):

            return 1

        # str(x) ,返回值必須是字符串

        def __str__(self):

            return str(self.value)

        # unicode(x)

        def __unicode__(self):

            return unicode(self.value)


        # abs(x)

        def __abs__(self):

            return abs(self.value)

        # hash(x)

        def __hash__(self):

            return hash(self.value)

        # hex(x)

        def __hex__(self):

            return hex(self.value)


        # int(x)

        def __int__(self):

            return int(self.value)

        # long(x)

        def __long__(self):

            return long(self.value)

        # float(x)

        def __float__(self):

            return float(self.value)


        # oct(x)

        def __oct__(self):

            return oct(self.value)

        # cmp(x, y)

        def __cmp__(self, value):

            return cmp(self.value, value)

        # coerce(x, y)

        def __coerce__(self, value):

            return coerce(self.value, value)

        # divmod(x, y)

        def __divmod__(self, value):

            return divmod(self.value, value)

        # divmod(y, x)

        def __rdivmod__(self, value):

            return divmod(self.value, value)


        # pow(x, y[, z])

        def __pow__(self, value):

            return pow(self.value, value[, z])

        # pow(y, x[, z])

        def __rpow__(self, value):

            return pow(self.value, value[, z])

        # repr(x])

        def __repr__(self, value):

            return repr(self.value)

        # size of S in memory, in bytes

        def __sizeof__(self, value):

            return 1



    a = Field(32)

    print(a < 12)  # 調用 a 的 __lt__

    print(12 > a)  # 調用 a 的 __lt__

    print(a >= 17)

    print(a != 15)

    print(a == 32)

    print(a + 8)   # 調用 a 的 __add__

    print(8 + a)   # 調用 a 的 __radd__

    print(a * 8)   # 調用 a 的 __mul__

    print(8 * a)   # 調用 a 的 __rmul__

    print(a / 8)   # python2時, 調用 a 的 __div__; python3時調用 __truediv__


    print(~a)

    print(-a)

    print(+a)

    #print(a.name2)

    print(a['name3'])

    print('name' in a)


    print(len(a))  # 調用 a 的 __len__

    print(str(a))  # 調用 a 的 __str__



    運算符表:

     二元運算符   特殊方法

        +       __add__,__radd__

        -       __sub__,__rsub__

        *       __mul__,__rmul__

        /       __div__,__rdiv__,__truediv__,__rtruediv__

        //      __floordiv__,__rfloordiv__

        %       __mod__,__rmod__

        **      __pow__,__rpow__

        <<      _lshift__,__rlshift__

        >>      __rshift__,__rrshift__

        &       __and__,__rand__

        ^       __xor__,__rxor__

        |       __or__,__ror__

        +=      __iaddr__

        -=      __isub__

        *=      __imul__

        /=      __idiv__,__itruediv__

        //=     __ifloordiv__

        %=      __imod__

        **=     __ipow__

        <<=     __ilshift__

        >>=     __irshift__

        &=      __iand__

        ^=      __ixor__

        |=      __ior__

        ==      __eq__

        !=,<>     __ne__

        >       __gt__

        <       __lt__

        >=      __ge__

        <=      __le__



################## 內置變量 end #############################

#############################################################



#############################################################

################## 內置函數 #################################

__import__(name[, globals[, locals[, fromlist[, level]]]])

    被 import 語句調用的函數。它的存在主要是爲了你可以用另外一個有兼容接口的函數 來改變 import 語句的語義.


abs(x)

    返回一個數的絕對值。參數也許是一個普通或長整型,或者一個浮點數。如果參數是一個複數,返回它的模。


all(iterable)

    如果迭代的所有元素都是真就返回真。版本2.5中新增.


any(iterable)

    如果迭代中有一個元素爲真就返回真。版本2.5中新增.


basestring()

    這個抽象類型是str和unicode的父類。它不能被調用或初始化,但是它可以使用來測試一個對象是否是str或unicode的實例。 isinstance(obj, basestring)等價於 isinstance(obj, (str, unicode)) 版本2.3中新增.


bool([x])

    將一個值轉換爲 Boolean,使用標準的真測試程序。如果x是假或忽略了,將返回 False;否則將返回 True.bool也是一個 class,它是 int 的一個子類,bool類不能進一步子類化。它僅有 False 和 True 兩個實例。


callable(object)

    如果 object 參數是可以調用的函數或者類就返回 True,否則返回 False 。返回 True,仍可能調用失敗,但返回 False,就不可能調用成功。

    可調用對象包括函數、方法、代碼對象、類和已經定義了“ __call__()”方法的類實例。

    如: a="123"; callable(a) 返回0;  callable(chr) 返回1


chr(i)

    返回一個ascii碼是整數i的字符的字符串。例如: chr(97)返回'a'.這和 ord()剛好相反。這參數在[0..255]之間,全部包含。如果超出這個範圍,就拋出 ValueError


classmethod(function)

    返回函數的一個類方法。一個類方法接收類作爲它的第一個潛在參數,就像一個實例方法接收一個實例。

    類方法不同於C++或Java的靜態方法。如果你想這樣做,使用 staticmethod()。


cmp(x, y)

    根據比較兩介對象x和y的結果,返回一個整數。如果x<y,返回-1,如果x==y,返回0,如果 x > y,根據比較結果返回一個正數.


coerce(number1, number2)

    (可以看成一個數值類型轉換函數)有兩個參數,都是數字,返回這兩個數字的一個列表,將這兩個數字的數據類型統一。python3去掉這函數。

    如: coerce(1,2j),返回(1+0j,2j)


compile(string, filename, kind[, flags[, dont_inherit]])

    編譯 string 爲一個代碼對象。代碼對象能夠通過 exec 語句執行或者通過調用 eval()計算。

    這filename參數指定代碼從哪個文件讀取。如果不從文件中讀取,就須傳遞一些可識別的值(通常使用'<string>')。

    kind參數指定哪種代碼被編譯;如果是包含一系列語句組成的子符串可以‘exec’,如果是由一個表達式組成,就'eval',如果由一個交互語句組成就‘singlw’(在後面的例子,表達式語句計算的結果不是 None 將打印出來)。

    當編譯一個多行語句時,應用兩個警告:必須以' '作爲行結束符,同時輸入必須至少以一個' '作爲結束。如果是以' '作爲行結束,使用 string 的 repalce() 方法將其改爲‘ ’.

    可先的參數flags和dont_inherit控制影響 string 編譯的 future 語句。更詳細的請參考英文文檔。


complex([real[, imag]])

    可把字符串或數字轉換爲複數。

    創建一個複數real + imag*j或者將一個 string 或者 number 轉化爲一個複數.

    如果第一個參數是一個字符串,它將作爲複數解釋,函數將被調用,而忽略第二個參數。第二個參數不可能是一個字符串。每一個參數都可能是一個數字類型包括複數.如果imag省略了, 它默認爲0,函數將當作一個數字轉換函數像 int(), long() and float().如果參數都省略了,將返回0j.


delattr(object, name)

    與 setattr()相對的,參數是一個對象和一個 string. string 必須是對象的一個屬性。函數刪除object這個名爲 string 的屬性。例如: delattr(x, 'foobar')等價於 del x.foobar


dict([arg])

    返回一個字典。

    例如,下面所有返回都等價於{"one": 2, "two": 3}:

        dict({'one': 2, 'two': 3})

        dict({'one': 2, 'two': 3}.items())

        dict({'one': 2, 'two': 3}.iteritems())

        dict(zip(('one', 'two'), (2, 3)))

        dict([['two', 3], ['one', 2]])

        dict(one=2, two=3)

    版本2.2中新增.


dir([object])

    列出模塊定義的標識符。標識符有函數、類和變量。

    當參數爲一個模塊名的時候,它返回模塊定義的名稱列表。如果不提供參數,它返回當前模塊中定義的名稱列表。

    注:因爲 dir()主要在交互提示下方便使用,它嘗試提供一給有意思的名字而不是嘗試提供嚴格的或與定義一樣的名字,在relrase中它的細節行爲也許會改變。


divmod(a, b)

    函數完成除法運算,返回商和餘數。

    如: divmod(10,3) 返回(3, 1); divmod(9,3) 返回(3, 0)


enumerate(iterable)

    返回 enumerate 對象. iterable 必須是一個序列, 一個迭代, 或者其它對象它支持迭代.

    enumerate()返回的 iterator 的 next()方法 返回一個元組包含一定的數目(從0開始)和從迭代中獲取的對應的值。

    enumerate() 對於獲取一個索引系列很有用: (0, seq[0]), (1, seq[1]), (2, seq[2]), .... 版本2.3中新增.


eval(expression[, globals[, locals]])

    該參數是一個字符串和可選的 globals 和 locals 。如果提供 globals,globals 必須是一個字典。如果提供 locals,locals 可以是任何映射對象。2.4版本修改:以前 locals 被要求是一個字典。

    expression參數是作爲一個Python表達式被分析和評價(技術上來說,一個條件列表)使用 globals 以及 locals 字典作爲 global 和 local 名字空間。

    如果提供了 globals 字典但沒有'__builtins__',當前 globals 在表達式被分析前被複制到 globals 中。這意味着表達式可以完全訪問標準 __builtin__ 模塊和受限的環境。如果 locals 字典省略則默認爲 globals 字典。如果兩個字典都被省略,表達式在調用 eval 的環境中執行。返回值是計算表達式的結果。語法錯誤報告爲 exceptions 。

    此函數也可以用來執行任意代碼的對象(如 compile()創建的)。在這種情況下,傳入一個代碼對象,而不是一個字符串。該代碼對象必須已編譯傳給'eval'作爲這種參數。

    提示: exec 語句支持是動態執行語句。 execfile()函數支持從一個文件中執行語句。 globals()和 locals()函數分別返回當前的 global 和 local 字典,這對使用 eval()或 execfile()很有幫助。


execfile(filename[, globals[, locals]])

    這個功能類似於 exec 語句,但分析一個文件,而不是一個字符串。這是不同之處在於它的 import 語句不使用模塊管理 - 它無條件讀取文件,並不會創建一個新的 module 。

    該參數是一個文件名和兩個可選字典。該文件被作爲Python語句序列(類似於一個模塊)使用 globals 和 locals 作爲 global and local 命名空間來分析和計算。如果提供 locals,locals 可以是任何映射對象。2.4版本修改:以前 locals 被要求是一個字典。如果 locals 字典省略則默認爲全局字典。如果兩個字典都被省略,表達式 execfile()被調用的環境中執行。返回值爲 None 。


    警告:默認的locals爲下面的locals():不要嘗試修改默認的本地詞典。如果你需要看到在函數execfile()返回後locals代碼的的影響,傳遞一個明確的locals字典。 execfile()不能用於依賴修改函數的locals。


file(filename[, mode[, bufsize]])

    文件類型的構造函數,`文件對象`。構造函數的參數與下面的內建的 open() 函數是一樣的。

    當打開一個文件,它是最好使用的 open(),而不是直接調用此構造函數。文件更適合檢驗類型(例如,isinstance(f, file))。


filter(function, iterable)

    把一個函數應用於序列中的每個項,並返回該函數返回真值時的所有項,從而過濾掉返回假值的所有項。

    function 返回 True 時從iterable的元素中構造一個列表。迭代可以是一個序列,一個支持迭代的容器,或一個迭代器,如果Iterable的是一個字符串或一個元組,其結果也有這種類型的,否則它始終是一個列表。如果 function 是 None, 假定它是恆等函數,即,迭代是 False 其所有元素都被刪除。

    請注意, filter(function,iterable),如果函數不爲 None 等價於[item for item in iterable if function(item)],如果函數爲 None 等價於[item for item in iterable if item]。


float( [x])

    將字符串或數字轉換或一個浮點數。如果參數是一個字符串,它必須包含一個可能帶符號的十進制或浮點數,可能嵌入空格。否則,參數可以是一個普通或長整數或浮點數,返回一個與之相同值的浮點數(在Python的浮點精度內)。如果沒有給出參數,返回0.0。

    注意:當傳遞一個字符串,可能會返回 NaN 和 Infinity,這取決於底層C庫。


float(x)

    把一個數字或字符串轉換成浮點數。


frozenset([iterable])

    返回一個frozenset對象,其元素來自於Iterable。 Frozensets組沒有更新的方法,但可以哈希和其他組成員或作爲字典鍵使用。一個frozenset的元素必須是不可改變。內部sets也應是frozenset對象。如果迭代沒有指定,返回一個新的空集,frozenset ([])。 版本2.4中新增


getattr(object, name[, default])

    返回object名爲name屬性的值。名稱必須是一個字符串。如果該字符串是對象的其中屬性名字,結果是該屬性的值。例如,getattr(x, 'foobar')相當於x.foobar。如果指定的屬性不存在,則返回默認提供的,否則拋出AttributeError。


globals()

    返回代表當前 global 符號表字典的字典。這始終是當前模塊字典(在一個函數或方法內,是在它被定義的模塊,而不是被調用的模塊)。


hasattr(object, name)

    該參數是一個對象和一個字符串。如果字符串是對象的其中一個屬性,結果爲 True,如果沒有返回 False 。 (這是通過調用的 getattr(對象名稱),看是否引發異常與否。)


hash(object)

    返回對象(如果有的話)的哈希值。哈希值是整數。它們被用來在詞典查找時,作爲一個快速比較字典keys鍵。具有相同的哈希值,數值相等(即使它們屬於不同的類型,因爲是1和1.0的情況)。


help([object])

    調用內置的幫助系統。(此功能是爲交互使用。)如果沒有給出參數,交互式幫助系統啓動解釋控制檯。如果參數是一個字符串,然後是字符串被作爲一個module,function,class,method,keyword或文檔主題名稱和幫助頁面名字進行查找後在控制檯上打印出來。如果參數是任何其他類型的對象,將產生該對象的一個幫助頁面。 版本2.2中新增.


hex(x)

    轉換一個(任意大小)整數爲十六進制字符串。其結果是一個有效的Python表達式。在2.4版本變更:原只產生一個無符號的文字。


id(object)

    返回對象的內存地址。

    這是一個整數(或長整型),這是保證是唯一的,與對象的生命週期一樣長。兩個非重疊的生命週期的對象可能有相同的 ID 值。


input([prompt])

    警告:此函數是不安全的,因爲用戶錯誤的輸入!它期待一個有效的Python表達式作爲輸入,如果輸入語法上是無效的,將拋出SyntaxError。如果地計算過程中有一個的錯誤,將拋出其他exceptions。 (另一方面,有時這是你爲特殊使用需要寫一個快速腳本。)

    如果readline模塊被加載,input()將使用它來提供詳細行編輯和歷史特性。

    考慮使用 raw_input() 函數作爲從用戶進行一般輸入。

    python3.x 開始有所變化


int([x[, radix]])

    轉換爲字符串或數字爲純整數。如果參數是一個字符串,它必須包含一個可能有符號的十進制數作爲一個Python整數,可能嵌入空格。

    以radix參數給出的基數爲基礎進行轉換(這是默認10),可以是任何在[2,36]範圍內的整數,或零。如果基數爲零,根據字符串的內容猜測正確的基數。如果指定的基數x是不是一個字符串,引發TypeError異常。否則,參數可以是一個普通或長整數或浮點數。轉換浮點數截斷爲整數(直到零)。如果參數是整數範圍之外的,將返回一個long object。如果沒有給出參數,返回0


isinstance(object, classinfo)

    測試對象類型。返回 True 如果該object參數是classinfo的一個實例,或其(直接或間接)子類的實例。也返回 True 如果classinfo是一種type對象(new-style class)和是該類型或其(直接或間接)子類的對象。如果object不是class一個的實例或者給定類型的對象,函數返回 False 。如果 classinfo 既不是一個類的對象也不是一個 type 的對象,它可能是一個包含類或類型的對象的 tuple, 也可能包含其他的遞歸元組(序列類型不接受)。如果 classinfo 不是一個類,類型或元組類,類型,或者這種元組,將拋出一個 TypeError 異常。

    自: type(obj) is classinfo 等效於 isinstance(object, classinfo)

    type(obj) in (int, long, float) 等效於 isinstance(object, (int, long, float)) # 多種類型的判斷


issubclass(class, classinfo)

    返回true如果class是classinfo(直接或間接)的子類。一個類被認爲是自己的子類。 classinfo可能是類對象元組,在這種情況下元組中的每個classinfo項將被進行測試。在其他任何情況下,拋出一個TypeError異常。


iter(o[, sentinel])

    返回一個迭代器對象。第一個參數有不同的解釋,視第二個參數的存在與否而定。如果沒有第二個參數,o必須是一個對象的集合,支持迭代協議(__iter__()方法),或者它必須支持序列協議(以整數0開始的參數__getitem__()方法)。如果它不支持這些協議,將拋出TypeError異常。如果第二個參數,sentinel,給出,然後o必須是可調用的對象。在這種情況下創造的每一個迭代器無參調用o它的 next()方法,如果返回值等於sentinel,將拋出StopIteration,否則將返回其它的值。


len(s)

    返回一個對象的長度。參數可以是一個序列(字符串,元組或列表)或映射(詞典)。


list([iterable])

    返回一個列表的items與可迭代的項目相同的順序且相同的items。

    iterable 可以是一個序列,一個容器,支持迭代,或一個迭代器對象。如果 iterable 已經是一個列表,將返回一個副本,類似的於iterable[:]。

    例如,list('abc')返回['a', 'b', 'c']和list( (1, 2, 3) ) 返回[1,2,3]。如果沒有給出參數,返回一個新的空列表,[]。


locals()

    更新並返回一個代表當前local符號表的字典。警告:本詞典的內容不應該被修改,更改可能不會影響由interpreter用作局部變量的值。


long([x[, radix]])

    轉換字符串或數字爲一個長整數。如果參數是一個字符串,它必須包含一個任意大小的可能有符號的數字,並有可能嵌入空格。radix參數解釋和int()一樣,而且只能當x是一個字符串時才需要它。否則,參數可以是一個普通或長整數或浮點數,返回與其相同值的長整數。轉換浮點數到截斷的整數(直到零)。如果沒有給出參數,返回0L。


map(function, iterable, ...)

    應用function在iterable的每一個項上並返回一個列表。如果有其他可迭代的參數,函數必須採取許多參數應用於來自所有iterables項。如果一個迭代比另一個短,將以None進行擴展。如果function是None,將假設爲identity function,如果有多個參數,map()返回一個列表包含所有iterables相應的項目的元組組成。可迭代的參數可能是一個序列或任何可迭代的對象,結果總是一個列表。


max(iterable[, args...][key])

    一個Iterable參數,返回其中一個最大的非空可迭代項,(如一個字符串,元組或列表)。如有多個參數,返回最大的參數。

    可選的key參數指定帶一個參數的排序函數,用於list.sort()。key參數,如果有,必須在以keyword的形式(例如,"max(a,b,c,key=func)")。


min(iterable[, args...][key])

    一個Iterable參數,返回其中一個最小的非空可迭代項,(如一個字符串,元組或列表)。如有多個參數,返回最小的參數。

    可選的key參數指定帶一個參數的排序函數,用於list.sort()。key參數,如果有,必須在以keyword的形式(例如,"max(a,b,c,key=func)")。


object()

    返回一個新特徵的對象。object是所有new style class的基類。它的方法是新樣式類的所有實例共有的。


oct(x)

    轉換一(任意大小)整數到一個八進制字符串。其結果是一個有效的Python表達式。


open(filename[, mode[, bufsize]])

    打開一個文件,返回一個在3.9節中描述的文件類型的對象,`File Objects'。如果文件無法打開,IOError異常引發。當打開一個文件,最好調用open(),而不是直接用file構造。

    前兩個參數與stdio的 fopen()函數一樣:filename是要打開的文件名,mode是一個字符串,表示該文件是如何被打開。

    mode,最常用的值是'r'讀,'w'寫(文件如果已存在就截斷),和'a'追加(在一些Unix系統意味着所有寫入追加到文件尾部,無論其現在的seek位置)。如果模式被省略,默認爲'r'等。當打開一個二進制文件,你應該模式值加上'b',打開二進制模式,從而提高可行性。 (在某些不區分二進制文件和文本文件的系統追加‘b’,,它將作爲文檔)。下面是mode的可能值:

    可選bufsize參數指定文件的所需緩衝區大小:0表示無緩衝,1表示行緩衝,任何其他的正數使用其大小(在約)的一個緩衝區。負數bufsize,使用系統默認,這tty設備通常使用行緩衝和其他文件的完全緩衝。如果省略,使用系統默認。

    模式'r+', 'w+'和'a+'打開文件進行更新(請注意,'w+'截斷該文件)。附加'b'的模式在區分二進制和文本文件的系統上以二進制方式打開文件,系統上沒有這個區別,加入了'b'沒有效果。


ord(c)

    返回一個字符串參數的ASCII碼或Unicode值。給定一個長度爲1的字符串,返回一個整數,當參數是一個Unicode對象,代表字符的 Unicode 代碼,或參數是一個8位字符串,代表其字節值。

    例如,ord('a')返回整數97,ord(u'\u2020')返回8224。這是8位串chr()和用於Unicode對象的unichr()的逆函數。如果給出Unicode參數和Python是UCS2 Unicode的,字符的代碼點必須在範圍[0 .. 65535]內,否則字符串的長度是2,拋出一個 TypeErro 。


pow(x, y[, z])

    返回x的Y次方,如果給出z,返回x的y次方,模Z(比pow(x, y) % z更有效)的。這兩個參數的形式pow(x, y),相當於:x ** y


property([fget[, fset[, fdel[, doc]]]])

    返回一個new-style類(從object派生的類)的屬性。

    fget是一個獲取屬性值的function,同樣fset是設置屬性值的function,fdel爲刪除屬性的函數。典型的用途是定義一個託管屬性x:


range([start,] stop[, step])

    函數可按參數生成連續的有序整數列表。

    這是一個通用函數來創建包含算術級數的列表,這是經常使用於循環。該參數必須是普通整數。如果step參數被省略,默認爲1。如果省略start參數,默認爲0。完×××式是返回一個普通整數列表[start, start + step, start + 2 * step, ...]。step不能爲零(否則引發ValueError)。


raw_input([prompt])

    如果prompt參數存在,它被寫入到標準輸出,結尾沒有換行。然後函數從輸入行讀取,將其轉換爲一個字符串(去掉換行),後返回。當爲EOF,拋出EOFError。例如:

    如果的ReadLine模塊被加載,然後raw_input()將使用它來提供詳細行編輯和歷史特性。


reduce(function, iterable[, initializer])

    使用帶兩參數的函數從左到右計算iterable的項,reduce這iterable得到一個數字。(累計計算結果,直到計算完所有項)

    例如: reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) 就是計算 ((((1+2)+3)+4)+5)。

    左參數x,是累加值和右邊的參數,y,是iterable中更新的值。如果可選的initializer存在,在計算中擺在可迭代的項的前面,當iterable爲空時,作爲默認。如果沒有給出initializer,則只包含一項,返回第一項。


reload(module)

    重新導入先前導入的模塊。該參數必須是一個模塊對象,因此它之前必須已成功導入。如果您使用外部編輯器編輯源文件的模塊,並想不離開Python解釋器嘗試新版本,這是有用的。返回值是模塊對象(與module參數相同的值)。


repr(object)

    返回一個字符串,其中包含一個對象的可打印形式。有時是對能夠訪問一個普通的函數的操作很有用。對於許多類型,該函數使得試圖返回一個字符串,會產生一個對象與傳遞給 eval() 相同的值產生的對象一樣。


reversed(seq)

    返回一個反向迭代器。seq必須是一個支持序列協議的對象(__len__()方法和__getitem__()以0開始的整數參數的方法) 版本2.4中新增


round(x[, n])

    返回浮點值x四捨五入到小數點後n位後數字。如果n被省略,默認爲零。結果是一個浮點數。


set([iterable])

    返回其元素都是從iterable得到的set。元素必須是不可改變的。如果iterable沒有指定,返回一個新的空集,設置([]). 版本2.4中新增


setattr(object, name, value)

    與getattr()相對應。該參數是一個對象,一個字符串和一個任意值。該字符串可以是現有屬性名稱或一個新的屬性。函數分配給該屬性值,只要該對象允許的話。例如,setattr(x, 'foobar', 123),相當於x.foobar = 123。


slice([start,] stop[, step])

    返回一個切片對象,它表示的是range(start, stop, step)指定的範圍。start和step參數默認爲None。切片對象有隻讀數據屬性start,stop和step,它只是返回參數值(或默認)。沒有其他明確的功能,但它們的作爲數值Python和其他第三方擴展使用。當使用擴展索引語法時也產生切片對象。例如:“a[start:stop:step]”或“a[start:stop, i]”。


sorted( iterable[, cmp[, key[, reverse]]])

    返回一個新的排序的列表,包含Iterable的項。

    可選參數cmp,key,reverse與list.sort()具相同涵義(詳見第3.6.4)。

    cmp指定帶兩個參數(Iterable的元素),返回自一個負數,零或正數的函數“cmp=lambda x,y: cmp(x.lower(), y.lower())“。

    key指定帶一個參數的函數,用來從列表每個元素中提取一個比較key:“key=str.lower”

    reverse是一個布爾值。如果設置爲True,則對列表中的元素進行排序,同時每一次比較都是逆向的。

    一般而言,key和reverse轉換過程是遠遠快於指定一個相當於cmp的功能。這是因爲cmp是爲每個列表元素調用很多次,而key和reverse接觸每個元素只有一次。

    版本2.4中新增


staticmethod( function)

    函數返回一個靜態方法。靜態方法沒有接收一個隱含的第一個參數。要聲明一個靜態方法,如下:

    class C:

        @staticmethod

        def f(arg1, arg2, ...): ...


    @staticmethod 形式 是一個function decorator

    它即可以在類上如C.f()進行調用,也可以在實例上,如:C().f()。實例被忽略,除了類。

    在Python靜態方法類似於Java或C++的。對於更先進的概念,見classmethod()。


str([object])

    返回對象的可打印字符串。對於字符串,這將返回字符串本身。

    與 repr(object)不同的是, str(object)並不總是試圖返回一個 eval()可以接受的字符串,其目標是返回一個可打印字符串。如果沒有給出參數,返回空字符串''。


sum(iterable[, start])

    求start和可迭代的從左至右的項和並返回總和。start默認爲0。在可迭代的項,通常是數字,不能是字符串。快速,正確的連接的字符串序列的方法是通過調用''.join(sequence)。注意sum(range(n), m)相當於reduce(operator.add, range(n), m)。 版本2.3中新增.


super(type[, object-or-type])

    返回類型的超類。如果第二個參數被省略,返回的超級對象是未綁定。如果第二個參數是一個對象,isinstance(obj, type)必須是true。如果第二個參數是一個類型,issubclass(type2, type)必須是true。super() 只能用於新型類。

    請注意,super是作爲顯式的點屬性綁定過程查找的一部分,例如“super(C, self).__getitem__(name)”。因此,super是未定義對於使用語句或操作進行隱式的查找,如“super(C, self)[name]”。 版本2.2中新增.


tuple([iterable])

    把序列對象轉換成 tuple 。返回一個元組的items與可迭代的iterable是相同的且有相同的順序。iterable可能是一個序列,容器支持迭代,或迭代器對象。如果iterable是元組,直接返回。

    例如,tuple('abc')返回('a', 'b', 'c') 和tuple([1, 2, 3])返回(1, 2, 3)。如果沒有給出參數,返回一個新的空元組,()。


type(object)

    返回對象的類型。返回值是一個類型對象。


type(name, bases, dict)

    返回一個新的類型的對象。這基本上是類聲明的動態形式。該name字符串是類名,成爲__name__的屬性;bases元組詳細列明瞭基類,併成爲__bases__的屬性,以及dict字典是命名空間定義爲類體,成爲 __dict__ 屬性。

    版本2.2中新增.


unichr(i)

    返回一個Unicode碼爲整數i的字符的Unicode字符串。例如,unichr(97)返回字符串u'a'。這是Unicode字符串的 ord()的逆函數。參數的有效範圍取決於Python如何被配置 - 它可以是UCS2 [0 .. 0xFFFF的]或UCS4 [0 .. 0x10FFFF]。否則引發ValueError。 版本2.0中新增


unicode([object[, encoding [, errors]]])

    返回object的Unicode版本字符串,使用下列方式之一:

    如果給出encoding和/或errors,Unicode()將解碼可以是一個8位字符串或使用encoding×××字符緩衝區的對象。編encoding參數是一個編碼名稱的字符串;如果encoding不知道,拋出LookupError。錯誤處理是根據errors,errors指定字符是在輸入編碼無效時的處理方案。如果錯誤是'strict'(默認),引發ValueError,而'ignore'將忽略錯誤,以及'replace'值的導致官方Unicode替換字符,U+FFFD,用來取代輸入的不能解碼的字符。另見編×××模塊。

    如果沒有可選參數,Unicode()將模仿 str(),但它返回Unicode字符串,而不是8位字符串。更確切地說,如果對象是一個Unicode字符串或其子類將返回不帶任何附加解碼的Unicode字符串。

    對於對象提供 __unicode__()方法,它將不帶參數調用這種方法來創建一個Unicode字符串。對於其他所有對象,8位字符串版本或請求representation,使用編碼'strict'模式的默認編×××轉換爲Unicode字符串。


vars([object])

    如果沒有參數,根據現在的local符號表返回一個字典。如果是一個模塊,類或類的實例對象作爲參數(或其它任何有__dict__屬性),根據對象的符號表返回一個字典。返回的字典不應被被修改:在相應符號表上的影響是未定義的。


xrange([start,] stop[, step])

    與 range()類似,但 xrnage()並不創建列表,而是返回一個xrange對象,它的行爲與列表相似,但是隻在需要時才計算列表值,當列表很大時,這個特性能爲我們節省內存。

    這個功能非常類似於range(),但返回一個'xrange object'而不是一個列表。這是一個不透明的序列類型,包含相應的列表相同的值而實際上沒有儲存這些值。xrange的優勢()比range()是很小的(xrange()還是要創造請求的值),除非使用一個非常大的範圍內存的機器或所有元素從來沒有使用過(例如循環通常是被打破終止的)。

    注:xrange()是爲了簡單和快速而設計的。施加了一定的限制,以實現這一目標。 Python的C語言實現限制所有參數的爲native C longs(“short”Python整數),並要求在這些elements都與native C long兼容。


zip([iterable, ...])

    把兩個或多個序列中的相應項合併在一起,並以元組的格式返回它們,在處理完最短序列中的所有項後就停止。

    例如: zip([1,2,3],[4,5],[7,8,9])  返回: [(1, 4, 7), (2, 5, 8)]

    如果參數是一個序列,則zip()會以一元組的格式返回每個項,如:

    zip([1,2,3,4,5])  返回: [(1,), (2,), (3,), (4,), (5,)]

    不帶參數,它返回一個空列表。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章