天天看點

What's New in Python3.0

原文:What's New in Python 3.0

這篇文章主要介紹了相比于python2.6,python3.0的新特性。更詳細的介紹請參見python3.0的文檔。

Common Stumbling Blocks

本段簡單的列出容易使人出錯的變動。

  • print語句被print()函數取代了,可以使用關鍵字參數來替代老的print特殊文法。例如:
    1. Old: print "The answer is", 2*2
    2. New: print("The answer is", 2*2)
    3. Old: print x,                                      # 使用逗号結尾禁止換行
    4. New: print(x, end=" ")                     # 使用空格代替換行
    5. Old: print                                         # 輸出新行
    6. New: print()                                    # 輸出新行
    7. Old: print >>sys.stderr, "fatal error"
    8. New: print("fatal error", file=sys.stderr)
    9. Old: print (x, y)                               # 輸出repr((x, y))
    10. New: print((x, y))                           # 不同于print(x, y)!

    你可以自定義輸出項之間的分隔符:

         print("There are <", 2**32, "> possibilities!", sep="")

    輸出結果是:

         There are <4294967296> possibilities!

    注意:

    1. print()函數不支援老print語句的“軟空格”特性,例如,在python2.x中,print "A\n", "B"會輸出"A\nB\n",而python3.0中,print("A\n", "B")會輸出"A\n B\n"
    2. 學會漸漸習慣print()吧!
    3. 使用2to3源碼轉換工具時,所有的print語句被自動轉換成print()函數調用,對大項目,這是無需争論的。
  • python3.0使用字元串(strings)和bytes代替Unicode字元串和8位字元串,這意味着幾乎所有使用Unicode編碼和二進制資料的代碼都要改動。這個改動很不錯,在2.x的世界裡,無數的bug都是因為編碼問題。
  • map()和filter()傳回疊代器(iterators)
  • dict方法keys(),items(),values()傳回視圖(同樣是疊代器)而不是清單(list)
  • 内建的sorted()方法和list.sort()方法不再接受表示比較函數的cmp參數,使用key參數代替。
  • 1/2傳回浮點數,使用1//2能得到整數。
  • repr()函數對于long整數不再包含拖尾的L,是以不加判斷的去除最後一個字元會導緻去掉一個有用的數字

String and Bytes

  • 現在隻有一種字元串:str,它的行為和實作都很像2.x的unicode串。
  • basestring超類已經去掉了,2to3工具會把每個出現的basestring替換成str。
  • PEP3137:新類型bytes,用來表示二進制資料和編碼文本,str和bytes不能混合,需要時,必須進行顯示的轉換,轉換方法是str.encode()(str->bytes)和bytes.decode()(bytes->str).
  • 在原始字元串(raw strings)中所有反斜線都按字面量解釋,不再特殊處理Unicode轉義字元。
  • PEP3112:bytes字面量,例如b"abc",建立bytes執行個體。
  • PEP3120:預設源檔案編碼為UTF-8
  • PEP3131:可以使用非ASCII辨別符(然而,除了注釋中貢獻者的名字之外,标準庫仍然隻包含ASCII)
  • PEP3116:新的IO實作,API幾乎100%向後相容,二進制檔案使用bytes代替strings
  • 去除了StringIO和cStringIO子產品,取而代之的是io.StringIO或者io.BytesIO

PEP3101:字元串格式化的新方法

  • str.format方法(原文提到替代了%操作符,實際上,format方法和%的用法差别很大,各有所長)。

PEP3106:修補了dict的keys(),items(),values()方法

  • 删除了dict.iterkeys(),dict.itervalues()和dict.iteritems()
  • dict.keys(),dict.values()和dict.items()傳回dict相關資料的引用

PEP3107:函數注解(Function Annotations)

  • 注解函數參數和傳回值的标準化方法

Exception Stuff

  • PEP352:異常類必須繼承自BaseException,它異常結構的基類。
  • 移除了StandardError
  • Dropping sequence behavior (slicing!) and message attribute of exception instances.
  • PEP3109:抛出異常:現在必須使用raise Exception(args)而不是原來的raise Exception, args
  • PEP3110:捕獲異常,現在必須使用except Exception as identifier而不是原來的except Exception, identifier
  • PEP3134:異常鍊(Exception chain)。
  • 改良了一些windows不能加載模式時的異常資訊,具有本地化處理。

New Class and Metaclass Stuff

  • 移除了classic class
  • PEP3115:新的metaclass文法
  • PEP3119:抽象基類。
  • PEP3129:類包裝。
  • PEP3141:數字抽象基類

其他的語言變化

這裡列出大多數的python語言核心和内建函數的變化。

  • 移除了backticks(使用repr()代替)
  • 移除了<>(不等号,使用!=代替)
  • as和with變成了關鍵字
  • True,False和None變成了關鍵字
  • PEP237:long不存在了,隻有int,它和原來的long一樣。不再支援以L結尾的數字字面量。移除sys.maxint,因為int現在已經是無限大了
  • PEP238:int相除,傳回float
  • 改變了順序操作符的行為,例如x<y,當x和y類型不比對時抛出TypeError而不是傳回随即的bool值
  • 移除了__getslice__,文法a[i:j]被解釋成a.__getitem__(slice(i,j))
  • PEP3102:keyword-only arguments.在函數參數清單中,出現在*args之後的命名參數隻能使用"關鍵字參數"的形式調用
  • PEP3104:nonlocal聲明。使用nonlocal可以聲明一個外部變量(不是global變量)
  • PEP3111:raw_input()改名為input(),也就是說,新的input()函數從标準輸入裝置(sys.stdin)讀取一行并傳回(不包括行結束符),如果輸入過早終止,該函數抛出EOFError,如果想使用老的input(),可以使用eval(input())代替。
  • xrange()改名為range(),range()現在不是産生一個清單(list),而是一個疊代器。
  • PEP3113:移除了"元組參數拆包(tuple parameter unpacking)"。這種寫法已經不行了:

    def foo(a, (b, c)):...

    現在要這樣寫:

    def foo(a, b_c):

          b,c = b_c

  • PEP3114:next()重命名為__next__(),新的内建函數next()可以調用一個對象的__next__()方法。
  • PEP3127:新的八進制字面量,二進制字面量和bin()函數。你應該寫0o666而不是0666,oct()函數也做了響應的改動。同樣,0b1010等價于10,bin(10)傳回"0b1010"。0666這種寫法現在是錯誤的。
  • PEP3132:支援疊代器拆包。現在你可以這樣寫:

    a, b, *rest = some_seqence

    甚至象這樣:

    *rest, a = stuff

    一般情況下,rest對象是list,而等号右邊的對象是可疊代的

  • PEP3135:新的super()。你可以不适用任何參數調用super(),正确的參數和執行個體會被正确選擇。如果使用參數,它的行為不變,和以前一樣。
  • zip(),map(),filter()傳回疊代器。
  • 移除了string.letters和它的朋友們(string.lowcase和string.uppercase),現在上場的是string.ascii_letters等
  • 移除了apply(),callable(),exefile(),file(),reduce(),reload()
  • 移除了dict.has_key()。使用in操作符進行測試
  • exec語句沒有了,現在是exec()函數
  • 移除了__oct__()和__hex__()特殊方法。oct()和hex()方法使用__index__()
  • 移除了對__members__和__methods__的支援
  • nb_nonzero重命名為nb_bool,__nonzero__()重命名為__bool__()

Optimizations

  • 一般情況下,python 3.0比python 2.5慢33%左右。不過仍有提升空間。

子產品變動(新的,改進的和廢棄的)

  • 移除了cPickle子產品,可以使用pickle子產品代替。最終我們将會有一個透明高效的子產品。
  • 移除了imageop子產品
  • 移除了audiodev, Bastion, bsddb185, exceptions, linuxaudiodev, md5, MimeWriter, mimify, popen2, rexec, sets, sha, stringold, strop, sunaudiodev, timing和xmllib子產品
  • 移除了bsddb子產品(單獨釋出,可以從http://www.jcea.es/programacion/pybsddb.htm擷取)
  • 移除了new子產品
  • os.tmpnam()和os.tmpfile()函數被移動到tmpfile子產品下
  • tokenize子產品現在使用bytes工作。主要的入口點不再是generate_tokens,而是tokenize.tokenize()

Build and C API Changes

Python’s build process和C API的改動包括:

  • PEP3118:新的Buffer API
  • PEP3121:擴充子產品的的Initialization & Finalization
  • PEP3123:使PyObject_HEAD符合标準C

其他的改動和修複

在源碼裡分散一系列的改進和bug修複。changes log表明,從2.6到3.0,有XXX個改動和YYY的bug修複。

下一篇: Python3.0入門