天天看點

python3.X中簡單錯誤處理,和Python2差別

1.print

1.1 Print是一個函數

在Python3中print是個函數,這意味着在使用的時候必須帶上小括号,并且它是帶有參數的。

    >>> print 'hello world'

  SyntaxError: Missing parentheses in call to 'print'

   >>>

Python版本更新後,3.X的版本中去掉了很多的函數,在3.X版本的python中,print需要加上括号

如:

    >>> print ('hello world')

    hello world

    >>> 

 另:将資料輸出為一組時,python2.x直接在需要輸出資料後面加上“,”即可,但python3.x中使用此方法無效,應該使用如下代碼:

     >>>   print (item, end=" ")

格式化輸出

類似于C中的 printf,  %字元:标記轉換說明符的開始

在Python 3.2.3中  input和raw_input 整合了,沒有了raw_input

不換号:

# pythong3中,這個是python3中的寫法,注意end='',是一對單引号
for x in range(0,10):
    print(x,end= '')      

#python2中,是用一個逗号

for x in range(0,10):

print x,

0 1 2 3 4 5 6 7 8 9

1 2

<code

class

=

"hljs php"

>old: <span

class

=

"hljs-keyword"

>

print

(x, y)   <span

class

=

"hljs-comment"

>

# 列印出元組(x, y)

<span

class

=

"hljs-keyword"

>new: <span

class

=

"hljs-keyword"

>

print

((x, y))  <span

class

=

"hljs-comment"

>

# 同上,在python3中print(x, y)的結果是跟這不同的</span></span></span></span></span></code>

在Python3中還可以定義分隔符,使用參數sep來指定.

上面代碼的結果如下:

注意:

  • print()函數不支援Python2.X中print中的“軟空格”。在Python2.X中,print "A\n", "B"的結果是"A\nB\n";而在Python3中print("A\n", "B")的結果是"A\n B\n"。
  • 在剛開始使用Python3的時候,你會發現你經常在互動模式下你還是經常使用老式的文法print x,是時候鍛煉你的手指用print(x)來取代它啦。
  • 如果你的項目比較大,而又想更新到Python3的時候,不用擔心,2to3這個工具會将所有的print語句轉換為print()函數。

2.input

   >>> myName=raw_input('Ener your name:')

   Traceback (most recent call last):

   File "<pyshell#129>", line 1, in <module>

   myName=raw_input('Ener your name:')

   NameError: name 'raw_input' is not defined

   >>> 

  同1,因版本問題。可直接用input代替

如:

     >>> myName=input('Ener your name:')

    Ener your name:cookie

    >>>

3.decimal

     >>> print (decimal.Decimal('1.1'))

    Traceback (most recent call last):

    File "C:/Users/cookie/Desktop/bb.py", line 2, in <module>

    print (decimal.Decimal('1.1'))

    NameError: name 'decimal' is not defined

    >>> 

錯誤提示‘decimal’ 未定義,導入decimal包即可

如:

     >>> import decimal

     >>> print (decimal.Decimal('1.1'))

         1.1

     >>> 

4.使用Views和Iterators代替Lists

  • dict的方法dict.keys(),dict.items(),dict.values()不會再傳回清單,而是傳回一個易讀的“views”。這樣一來,像這樣的文法将不再有用了:k = d.keys();k.sort(),你可以使用k = sorted(d)來代替。sorted(d)在Python2.5及以後的版本中也有用,但是Python3效率更高了。
1 2 3 4 5

<code

class

=

"hljs bash"

>d

=

{<span

class

=

"hljs-string"

>

'a'

:

1

}

d.keys()     <span

class

=

"hljs-comment"

>

# dict_keys(['a']) 

d.items()    <span

class

=

"hljs-comment"

>

# dict_items([('a', 1)]) 

d.values()   <span

class

=

"hljs-comment"

>

# dict_values([1]) 

k

=

d.keys(); k.sort()     <span

class

=

"hljs-comment"

>

# AttributeError: 'dict_keys' object has no attribute 'sort'</span></span></span></span></span></code>

  • 同樣,dict.iterkeys(),dict.iteritems(),dict.itervalues()方法也不再支援。
  • map()和filter()将傳回iterators。如果你真的想要得到清單,list(map(...))是一個快速的方法,但是更好的方法是使用清單推導(尤其是原代碼使用了lambda表達式的時候),或者重寫原來的代碼,改為不需要使用清單。特别是map()會給函數帶來副作用,正确的方法是改為使用for循環,因為建立一個清單是非常浪費的事情。
  • Python3中的range()函數跟Python2.X的xrange()函數的作用是一樣的,這樣可以使用任意的數字,Python3中去除了xrange()函數。
  • zip()在Python3中傳回的是一個疊代器。

5 比較符

     Python3簡化了比較符。

  • 在使用比較符(<,<=,>=,>)時,當相比較的操作數的排序是沒有意義的時候将會抛出TypeError異常,是以像1 < '',0 > None,len <= len這樣的語句不再合法了。None < None也會抛出TypeError異常,而不是傳回False。你應該明白了,胡亂的比較是沒有意義的,相比較的元素必須是能夠比較的才行。需要注意的是,==和!=不包括在内,因為不通類型的,無法比較元素總是不等于另一個的。
  • builtin.sorted和list.sort()不再有提供比較函數的cmp參數,隻有參數key和reverse。
  • cmp()函數應該當做被去除了,__cmp__()特殊方法也不再支援。在需要的時候使用__lt__,__eg__和__hash__。

6 整型數

  • 從本質上來說,long重命名了int,因為在内置隻有一個名為int的整型,但它基本跟之前的long一樣。
  • 像1/2這樣的語句将傳回float,即0.5。使用1//2來擷取整型,這也是之前版本所謂的“地闆除”。
  • 移除了sys.maxint,因為整型數已經沒了限制。sys.maxsize可以用來當做一個比任何清單和字元串下标都要大的整型數。
  • repr()中比較大的整型數将不再帶有L字尾。
  • 八進制數的字面量使用0o720代替了0720。

7 Text Vs. Data 代替 Unicode Vs. 8-bit

     Python3中改變了二進制資料和Unicode字元串。

  • Python3使用文本和(二進制)資料的理念代替之前的Unicode字元串和8-bit字元串,所有的文本預設是Unicode編碼。使用str類型儲存文本,使用bytes類型儲存資料。當你混淆文本和資料的時候Python3會抛出TypeError的錯誤。
  • 不能再使用u"..."字面量表示unicode文本,而必須使用b"..."字面量表示二進制資料。
  • 因為str和bytes不能弄混,是以你必須顯式地将他們進行轉換。使用str.encode()将str轉換為bytes,使用bytes.decode()将bytes轉換為str,也可以使用bytes(s, encoding=...)和str(b, encoding=...)。
  • str和bytes都是不可變的類型,有一個分離的可變類型的bytearray可以儲存緩存的二進制資料,所有能夠接受bytes的API都能夠使用bytearray。這些可變的API是基于collections.MutableSequence的。
  • 移除了抽象類型basestring,使用str代替。
  • 檔案預設使用文本類型打開,這也是open()函數預設的。如果要打開二進制檔案必須使用b參數,否則會出現錯誤,而不會默默地提供錯誤的資料。
  • 檔案名都使用unicode字元串傳入和輸出,變量名也是,是以可以使用中文作為變量名,例如 中國="China"; print(中國) 。關于 python2 的編碼問題請參考:詳解python中文編碼與處理 http://my.oschina.net/leejun2005/blog/74430
  • 一些關于系統的API,如os.environ和sys.argv,當系統允許bytes并且不能正常轉換為unicode的話,也會出現問題。是以,将系統的LANG設定好是最好的做法。
  • repr()函數不再轉義非ASCII字元。
  • 代碼預設為UTF-8編碼。
  • 移除了StringIO和cStringIO。加入了io子產品,并分别使用io.StringIO和io.BytesIO分别用于text和data。

2、文法改變

2.1 新增文法

  • 函數變量和傳回值annotations。
  • Keyword-only變量。
  • nonlocal聲明。使用nonlocal x可以直接引用一個外部作用域的變量,但不是全局變量。
  • 擴充了疊代的解包。
1 2 3 4

<code

class

=

"hljs bash"

>(a,

*

rest, b)

=

range

(

5

a   <span

class

=

"hljs-comment"

>

# 0

rest <span

class

=

"hljs-comment"

>

# [1,2,3]

b   <span

class

=

"hljs-comment"

>

# 4</span></span></span></code>

  • 字典推導。{k: v for k, v in stuff }。
t = ((1,1), (2,2))  
d = {k: v for k, v in t}  
d # {1: 1, 2: 2} 
           
  • 集合推導。{x for x in stuff},與set(stuff)效果一樣,但是更加靈活。
  • 八進制字面量0o720。
  • 二進制字面量0b1010,相當于新的内置函數bin()。
  • 位元組字面量b或者B,相當于新的内置函數bytes()。

2.2 改變的文法

  • 将except exc, var改為except exc as var。
  • 新的元類文法。
1 2 3 4 5 6 7 8

<code

class

=

"hljs python"

><span

class

=

"hljs-comment"

>

# old 

<span

class

=

"hljs-class"

><span

class

=

"hljs-keyword"

><span

class

=

"hljs-class"

><span

class

=

"hljs-keyword"

>

class

<span

class

=

"hljs-class"

> <span

class

=

"hljs-title"

><span

class

=

"hljs-class"

><span

class

=

"hljs-title"

>C<span

class

=

"hljs-class"

>:

__metaclass__

=

M

.... 

<span

class

=

"hljs-comment"

>

# new 

<span

class

=

"hljs-class"

><span

class

=

"hljs-keyword"

><span

class

=

"hljs-class"

><span

class

=

"hljs-keyword"

>

class

<span

class

=

"hljs-class"

> <span

class

=

"hljs-title"

><span

class

=

"hljs-class"

><span

class

=

"hljs-title"

>C<span

class

=

"hljs-params"

><span

class

=

"hljs-class"

><span

class

=

"hljs-params"

>(metaclass

=

M)<span

class

=

"hljs-class"

>: 

....<

/

span><

/

span><

/

span><

/

span><

/

span><

/

span><

/

span><

/

span><

/

span><

/

span><

/

span><

/

span><

/

span><

/

span><

/

span><

/

span><

/

span><

/

span><

/

span><

/

span><

/

span><

/

span><

/

span><

/

code>

  • 清單推導不再支援[... for var in item1, item2, ...],必須寫成[... for var in (item1, item2,...)]。
  • 省略号...作為連續表達式可以用于任何地方,之前隻能用于分片中。但是必須連續寫,之前帶空格的. . .不再支援。

2.3 移除的文法

  • 移除了元組的解包。不能再寫def foo(a, (b, c)): ....,需要寫成def foo(a, b_c):b, c = b_c。
  • 移除<>,使用!=代替。
  • exec()不能再作為關鍵詞,隻能作為一個函數。并且exec()不再支援流變量,如exec(f)需寫成exec(f.read())。
  • 整型不支援l/L字尾。
  • 字元串不支援'u/U'字首。
  • from module import *隻能用在子產品級,在函數中不可使用。
  • 所有不以.開始的import語句均作為絕對路徑的import對待。
  • 移除了經典類。

3、推薦閱讀:

使用 2to3 将代碼移植到 Python 3

http://woodpecker.org.cn/diveintopython3/porting-code-to-python-3-with-2to3.html

Moving from Python 2 to Python 3

http://ptgmedia.pearsoncmg.com/imprint_downloads/informit/promotions/python/python2python3.pdf