Hầu như tất cả các chương trình Python 2 đều cần một số sửa đổi để chạy một cách bình thường trong môi trường Python 3. Để đơn giản hóa quá trình chuyển đổi này, Python 3 có một tập lệnh thực tế được gọi là 2to3 (Utility Script), tập lệnh này sẽ lấy tệp nguồn chương trình Python 2 của bạn làm đầu vào và sau đó tự động chuyển đổi nó thành dạng Python 3.
Trong Python 2, print là một câu nói. Bất cứ điều gì bạn muốn xuất ra, bạn chỉ cần đặt chúng sau từ khóa print. Trong Python 3, print () là một hàm. Giống như các hàm khác, print () yêu cầu bạn đưa ra những gì bạn muốn xuất ra dưới dạng tham số cho nó.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | print() | |
| ② | print 1 | print(1) |
| ③ | print 1,2 | print(1,2) |
| ④ | print 1,2, | print(1,2,end=’ ‘) |
| ⑤ | print >>sys.stderr,1,2,3 | print(1,2,3, file=sys.stderr) |
1, để xuất ra một dòng trống, cần gọi print không có tham số ((() 2 , để xuất ra một giá trị riêng biệt, bạn cần đặt giá trị này làm một tham số print ((). 3, để xuất ra hai giá trị được tách ra bởi một khoảng trống, gọi print ((() bằng hai tham số. Trong Python 2, nếu bạn sử dụng dấu chấm (-) như là kết thúc của câu print, nó sẽ tách kết quả đầu ra bằng một khoảng trống, và sau đó xuất ra một khoảng trống theo sau (trailing space) mà không xuất ra carriage return. Trong Python 3, bạn có thể đạt được hiệu quả tương tự bằng cách truyền end=’ ‘ như một tham số từ khóa cho print. Trong Python 3, bạn có thể thực hiện chức năng tương tự bằng cách chuyển hướng đầu ra vào một đường ống bằng cách chuyển giá trị của file tham số từ khóa của đường ống sang print (). Định nghĩa mặc định của file tham số là std.stdout, vì vậy định lại giá trị của nó sẽ khiến print () xuất ra một đường ống khác.
Python 2 có hai loại chuỗi:Dãy ký tự UnicodeVàDãy ký tự không phải là UnicodePython 3 chỉ có một loại:Unicode strings。
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | u’PapayaWhip’ | ‘PapayaWhip’ |
| ② | ur’PapayaWhip\foo’ | r’PapayaWhip\foo’ |
Các chuỗi Unicode trong Python 2 được gọi là chuỗi thông thường trong Python 3, bởi vì các chuỗi trong Python 3 luôn luôn có dạng Unicode. Unicode raw string ((raw string) ((: Python không tự động chuyển đổi đường cong ngược khi sử dụng chuỗi này)“) cũng được thay thế bằng các chuỗi thông thường, bởi vì trong Python 3, tất cả các chuỗi gốc đều được mã hóa bằng Unicode.
Python 2 có hai hàm toàn cầu có thể bắt buộc chuyển đổi đối tượng thành chuỗi: unicode ((() chuyển đổi đối tượng thành chuỗi Unicode, và str ((() chuyển đổi đối tượng thành chuỗi không Unicode. Python 3 chỉ có một loại chuỗi, chuỗi Unicode, vì vậy hàm str ((() có thể thực hiện tất cả các chức năng.Unicode () không còn tồn tại trong Python 3.)
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | unicode(anything) | str(anything) |
Python 2 có các loại int và long dành cho các số không có điểm nổi. Giá trị tối đa của loại int không được vượt quá sys.maxint, và giá trị tối đa này là liên quan đến nền tảng. Các kiểu nguyên tố dài có thể được xác định bằng cách thêm một L vào cuối số, rõ ràng là nó rộng hơn phạm vi số của loại int. Trong Python 3, chỉ có một loại nguyên tố int, trong hầu hết các trường hợp, nó giống như kiểu nguyên tố dài trong Python 2. Vì hai loại nguyên tố không còn tồn tại, không cần phải sử dụng ngữ pháp đặc biệt để phân biệt chúng.
Đọc thêm: PEP 237: Thống nhất toàn bộ dài và toàn bộ
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | x = 1000000000000L | x = 1000000000000 |
| ② | x = 0xFFFFFFFFFFFFL | x = 0xFFFFFFFFFFFF |
| ③ | long(x) | int(x) |
| ④ | type(x) is long | type(x) is int |
| ⑤ | isinstance(x,long) | isinstance(x,int) |
Trong Python 2, số nguyên dài thập phân được thay thế bằng số nguyên bình thường thập phân trong Python 3. Trong Python 2, số nguyên dài mười sáu chữ số được thay thế bằng số nguyên bình thường mười sáu chữ số trong Python 3. Trong Python 3, chúng ta không còn sử dụng kiểu chữ dài nữa, vì nó đã không còn tồn tại.Chức năng long ((() tự nhiên cũng không còn nữa. Để ép buộc chuyển đổi một biến thành dạng nguyên, bạn có thể sử dụng hàm int ((()。 Kiểm tra xem một biến có phải là integer hay không, lấy loại dữ liệu của nó và so sánh với một loại int ((không phải là long)). Bạn cũng có thể sử dụng hàm insinstance (()) để kiểm tra kiểu dữ liệu; một lần nữa, nhấn mạnh rằng sử dụng int, thay vì long, để kiểm tra kiểu số nguyên.
Python 2 hỗ trợ <> đồng nghĩa với !=. Python 3 chỉ hỗ trợ !=, không còn hỗ trợ <> nữa.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | if x <> y: | if x != y: |
| ② | if x <> y<> z: | if x != y!= z: |
1, đơn giản là so sánh. 2, so sánh giữa ba giá trị tương đối phức tạp.
Trong Python 2, đối tượng từ điển has_key ((() phương thức dùng để kiểm tra từ điển có chứa một khóa cụ thể không (((key) }} Python 3 không còn hỗ trợ phương thức này nữa }} bạn cần sử dụnginHoạt động
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | a_dictionary.has_key(‘PapayaWhip’) | ‘PapayaWhip’ in a_dictionary |
| ② | a_dictionary.has_key(x) or a_dictionary.has_key(y) | x in a_dictionary or y in a_dictionary |
| ③ | a_dictionary.has_key(x or y) | (x or y) in a_dictionary |
| ④ | a_dictionary.has_key(x + y) | (x + y) in a_dictionary |
| ⑤ | x + a_dictionary.has_key(y) | x + (y in a_dictionary) |
1, dạng đơn giản nhất. 2 ∈ OR có ưu tiên thấp hơn so với ∈ IN, vì vậy không cần phải thêm dấu ngoặc kép. 3 , Mặt khác, vì cùng một lý do, or có ưu tiên thấp hơn in, cần thêm dấu ngoặc kép. _dictionary một phím. 4 ∙ Các toán tử in có ưu tiên thấp hơn so với các toán tử +, vì vậy hình thức này trong mã không cần phải có dấu ngoặc kép, nhưng 2to3 vẫn được thêm vào. 5, hình thức này cần phải có dấu ngoặc kép, vì in có ưu tiên thấp hơn + .
Trong Python 2, nhiều phương thức từ điển trả về giá trị là danh sách. Trong đó, các phương thức được sử dụng nhiều nhất có các khóa, các mục và các giá trị. Trong Python 3, tất cả các phương thức trên trả về giá trị thay đổi thành dynamic view. Trong một số môi trường ngữ cảnh, thay đổi này không có tác động.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | a_dictionary.keys() | list(a_dictionary.keys()) |
| ② | a_dictionary.items() | list(a_dictionary.items()) |
| ③ | a_dictionary.iterkeys() | iter(a_dictionary.keys()) |
| ④ | [i for iin a_dictionary.iterkeys()] | [i for iin a_dictionary.keys()] |
| ⑤ | min(a_dictionary.keys()) | no change |
Sử dụng hàm list () để chuyển đổi giá trị trả về của keys () thành một danh sách tĩnh, vì lý do bảo mật, 2to3 có thể bị lỗi. Mã như vậy có hiệu quả, nhưng nó kém hiệu quả hơn đối với việc sử dụng view. Bạn nên kiểm tra mã sau khi chuyển đổi để xem liệu bạn có cần danh sách hay không, và có lẽ view cũng có thể làm điều tương tự. 2 , đây là một cách khác để xem () về phương pháp () đối với các item () chuyển đổi của () vào danh sách. △ 2to3 đối với các giá trị () chuyển đổi của () trả về giá trị cũng tương tự. 3, Python 3 không còn hỗ trợ iterkeys (((). Nếu cần thiết, sử dụng iter ((() để chuyển đổi giá trị trả về của keys ((() thành một iterator. 4 2to3 có thể nhận ra phương thức iterkeys () được sử dụng trong phân tích danh sách, sau đó chuyển đổi nó thành phương thức keys () trong Python 3 mà không cần sử dụng iter () bổ sung để đóng gói giá trị trả về của nó. Điều này là khả thi vì giao diện là lặp. 5 2to3 cũng có thể nhận ra rằng các giá trị trả về của phương thức keys (()) được chuyển ngay cho một hàm khác sẽ đi qua toàn bộ chuỗi, vì vậy không cần thiết phải chuyển đổi giá trị trả về của keys (()) thành một danh sách. Ngược lại, hàm min ((() sẽ vui lòng đi qua góc nhìn. Quá trình này cũng có hiệu quả đối với min (((), max (((), sum (((), list (((), tuple (((), set (((), sorted (((), any ((() và all (().
Từ Python 2 đến Python 3, một số mô-đun trong bộ sưu tập tiêu chuẩn đã được đổi tên. Một số mô-đun liên quan đến nhau cũng được kết hợp hoặc tổ chức lại để làm cho mối liên quan này hợp lý hơn.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | import httplib | import http.client |
| ② | import Cookie | import http.cookies |
| ③ | import cookielib | import http.cookiejar |
| ④ | import BaseHTTPServer import SimpleHTTPServer import CGIHttpServer |
import http.server |
Mô-đun http.client thực hiện một thư viện cấp dưới, có thể được sử dụng để yêu cầu tài nguyên HTTP và phân tích phản hồi HTTP. Mô-đun http.cookies cung cấp một giao diện Python để lấy các cookie được gửi qua đầu HTTP Set-Cookie Các trình duyệt phổ biến thường lưu các cookie dưới dạng tệp trên ổ đĩa, và mô-đun http.cookiejar có thể xử lý các tệp này. Mô-đun http.server thực hiện một máy chủ HTTP cơ bản
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | 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 import urlencode |
from urllib.request import FancyURLopener from urllib.parse import urlencode |
| ⑥ | from urllib2 import Request from urllib2 import HTTPError |
from urllib.request import Request from urllib.error import HTTPError |
Trước đây, mô-đun urllib trong Python 2 có nhiều chức năng khác nhau, bao gồm urlopen () để lấy dữ liệu, và cũng hữu ích để chia URL thành các thành phần của nó. Các chức năng splitype () và splituser () trong gói urllib mới, các chức năng này được tổ chức một cách hợp lý hơn. 2to3 sẽ sửa đổi việc gọi các chức năng này để phù hợp với chương trình đặt tên mới. Trong Python 3, các mô-đun urllib2 trước đây đã được đưa vào urllib. Trong khi đó, những thứ bạn yêu thích nhất trong urllib2 sẽ xuất hiện một cách thường xuyên trong mô-đun urllib của Python 3, chẳng hạn như build_Opener () phương thức, Request object, HTTPBasicAuthHandler và friends。 Mô-đun urllib.parse trong Python 3 chứa tất cả các hàm phân tích của mô-đun urlparse trong Python 2. Mô-đun urllib.robotparse phân tích file robots.txt. Lớp FancyURLopener xử lý chuyển hướng HTTP và các mã trạng thái khác vẫn còn trong mô-đun urllib.request trong Python 3. Đối tượng Request vẫn còn trong urllib.request, nhưng các hằng số như HTTPError đã được chuyển sang urllib.error. Tôi có đề cập đến việc 2to3 cũng sẽ viết lại các function call của bạn không? Ví dụ, nếu bạn nhập urllib module vào mã Python 2 của bạn, và gọi urllib.urlopen () để lấy dữ liệu, 2to3 sẽ thay đổi cả câu lệnh import và function call.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | import urllib print urllib.urlopen(’http://diveintopython3.org/‘).read() | import urllib.request, urllib.parse, urllib.error print(urllib.request.urlopen(’http://diveintopython3.org/‘).read()) |
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | import dbm | import dbm.ndbm |
| ② | import gdbm | import dbm.gnu |
| ③ | import dbhash | import dbm.bsd |
| ④ | import dumbdbm | import dbm.dumb |
| ⑤ | import anydbm import whichdb |
import dbm |
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | import xmlrpclib | import xmlrpc.client |
| ② | import DocXMLRPCServer import SimpleXMLRPCServer |
import xmlrpc.server |
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | try: import cStringIO as StringIO except ImportError: import StringIO |
import io |
| ② | try: import cPickle as pickle except ImportError: import pickle |
import pickle |
| ③ | import _builtin_ | import builtins |
| ④ | import copy_reg | import copyreg |
| ⑤ | import Queue | import queue |
| ⑥ | import SocketServer | import socketserver |
| ⑦ | import ConfigParser | import configparser |
| ⑧ | import repr | import reprlib |
| ⑨ | import commands | import subprocess |
Trong Python 2, bạn thường làm như vậy, đầu tiên bạn thử nhập cStringIO thay cho StringIO, và nếu không thành công thì nhập StringIO. Đừng làm như vậy trong Python 3; mô-đun io sẽ giúp bạn xử lý vấn đề này. Nó sẽ tìm ra cách thực hiện nhanh nhất có thể và tự động sử dụng nó. Trong Python 2, nhập một triển khai Pickle nhanh nhất cũng là một cách hữu ích tương tự như trên. Trong Python 3, mô-đun Pickle sẽ tự động xử lý cho bạn, vì vậy đừng làm điều đó nữa. 3, Builtins module chứa các hàm toàn cầu, lớp và hằng số được sử dụng trong toàn bộ ngôn ngữ Python. Định nghĩa lại một hàm trong builtins module có nghĩa là định nghĩa lại hàm toàn cầu này ở khắp mọi nơi. Nghe có vẻ mạnh mẽ, nhưng cũng rất đáng sợ. 4, mô-đun copyreg đã thêm hỗ trợ cho mô-đun pickle cho các loại tùy chỉnh của người dùng được định nghĩa bằng ngôn ngữ C. 5. Mô-đun queue thực hiện một hàng đợi người sản xuất, người tiêu dùng đa (multi-producer, multi-consumer queue) [2]. 6, mô-đun socketserver cung cấp các lớp cơ bản phổ biến để thực hiện các socket server khác nhau. 7, mô-đun configparser được sử dụng để phân tích tệp cấu hình kiểu INI. 8, mô-đun reprlib đã thực hiện lại hàm repr () và thêm điều khiển về chiều dài của chuỗi biểu thị trước khi bị cắt. 9, mô-đun subprocess cho phép bạn tạo ra các subprocess, kết nối với các pipeline của chúng và lấy các giá trị trả về của chúng.
Trong Python 2, để thực hiện tham chiếu lẫn nhau của các mô-đun trong cùng một gói, bạn sẽ sử dụng import foo hoặc from foo import Bar. Thanh toán Python 2 sẽ tìm kiếmfoo.py trong thư mục hiện tại, sau đó tìm kiếm trong đường dẫn tìm kiếm của Python ((sys.path).
Giả sử bạn có nhiều tập tin trong cùng một thư mục như sau:
chardet/ | +–init.py | +–constants.py | +–mbcharsetprober.py | +–universaldetector.py
Bây giờ giả sử rằng universaldetector.py cần phải nhập toàn bộ constants.py, và một lớp trong mbcharsetprober.py nữa. Bạn sẽ làm gì?
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | import constants | from .import constants |
| ② | from mbcharsetprober import MultiByteCharSetProber | from .mbcharsetprober import MultiByteCharsetProber |
Trong ví dụ này, hai tệp này nằm trong cùng một thư mục, vì vậy sử dụng một câu riêng. Bạn cũng có thể nhập từ thư mục mẹ ((from .. import anothermodule) hoặc thư mục con. 2. Để nhập một lớp hoặc hàm cụ thể từ các mô-đun khác trực tiếp vào namespace của mô-đun của bạn, hãy thêm đường dẫn tương đối vào tên của mô-đun cần nhập và loại bỏ dấu gạch chéo cuối cùng ((slash) }}. Trong ví dụ này, mbcharsetprober.py và universaldetector.py nằm trong cùng một thư mục, vì vậy tên đường dẫn tương đối là một chữ số. Bạn cũng có thể nhập từ thư mục mẹ ((from .. import anothermodule) hoặc từ thư mục con.
Trong Python 2, iterator có phương thức next () để trả về mục tiếp theo trong chuỗi. Điều này cũng được thực hiện trong Python 3, nhưng bây giờ có một hàm toàn cầu mới next () sử dụng một iterator làm tham số.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | anIterator.next() | next(anIterator) |
| ② | a_function_that_returns_an_iterator().next() | next(a_function_that_returns_an_iterator()) |
|③|class A:
def next(self):
pass|class A:
def next(self):
pass|
|④|class A:
def next(self, x, y):
pass|no change |
|⑤|next = 42
for an_iterator in a_sequence_of_iterators:
an_iterator.next()|next = 42
for an_iterator in a_sequence_of_iterators:
an_iterator.next() |
1, ví dụ đơn giản nhất, bạn không còn gọi phương thức next (() của một nhân tố, bây giờ bạn chuyển bản thân nhân tố như là tham số cho hàm next (() của toàn cầu.
2, nếu bạn có một hàm trả về giá trị là hàm của hàm nhân, hãy gọi hàm này và chuyển kết quả thành tham số cho hàm next ((((script 2to3 đủ thông minh để thực hiện chuyển đổi này một cách chính xác)))
Nếu bạn định nghĩa một lớp của riêng bạn, và sử dụng nó như là một nhân tố, trong Python 3, bạn có thể định nghĩa một phương thức đặc biệt bằng cách sử dụng nó để tạo ra một lớp.next() để thực hiện.
4, nếu bạn định nghĩa một lớp mà nó có một next () và nó sử dụng một hoặc nhiều tham số, 2to3 sẽ không di chuyển nó khi thực hiện. Lớp này không thể được sử dụng như là một nhân, bởi vì phương thức next () của nó có tham số.
5, đây là một chút phức tạp. Nếu bạn tình cờ có một biến địa phương có tên là next, nó sẽ có ưu tiên cao hơn trong Python 3 so với hàm toàn cầu next (((). Trong trường hợp này, bạn cần gọi một phương thức đặc biệt của trình tự.next() để lấy phần tử tiếp theo trong chuỗi… hoặc, bạn có thể cấu trúc lại mã để biến local này không được gọi là next, nhưng 2to3 sẽ không làm điều đó cho bạn…)
Trong Python 2, phương thức filter() trả về một danh sách được lấy bằng một hàm trả về giá trị True hoặc False để kiểm tra từng mục trong chuỗi. Trong Python 3, hàm filter() trả về một nhân tố, không còn là danh sách nữa.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | filter(a_function, a_sequence) | list(filter(a_function, a_sequence)) |
| ② | list(filter(a_function, a_sequence)) | no change |
| ③ | filter(None, a_sequence) | [i for iin a_sequence if i] |
| ④ | for i in filter(None, a_sequence): | no change |
| ⑤ | [i for iin filter(a_function, a_sequence)] | no change |
1, trong trường hợp đơn giản nhất, 2to3 sẽ dùng hàm list () để đóng gói filter () và hàm list () sẽ đi qua các tham số của nó và trả về một danh sách. 2 , Tuy nhiên, nếu filter() được gọi đã được list() gói, 2to3 sẽ không xử lý nữa, vì trong trường hợp này, giá trị trả về của filter() là một iterator là không quan trọng. 3, Để xử lý ngữ pháp đặc biệt của filter ((None, …) thì 2to3 sẽ chuyển đổi lời gọi này từ ngữ pháp tương đương sang phân tích danh sách. 4, Không cần sửa đổi vì vòng lặp for sẽ đi qua toàn bộ chuỗi. 5, giống như trên, không cần phải sửa đổi, vì phân tích danh sách sẽ đi qua toàn bộ chuỗi, và ngay cả khi filter () trả về một trình tự, nó vẫn có thể hoạt động bình thường như filter () trả về danh sách trước đó.
Cũng giống như sự thay đổi của filter (), hàm map ()) bây giờ trả về một iterator. Trong Python 2, nó trả về một danh sách.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | map(a_function,‘PapayaWhip’) | list(map(a_function,‘PapayaWhip’)) |
| ② | map(None,‘PapayaWhip’) | list(‘PapayaWhip’) |
| ③ | map(lambda x: x+1,range(42)) | [x+1for x in range(42)] |
| ④ | for i in map(a_function, a_sequence): | no change |
| ⑤ | [i for iin map(a_function,a_sequence)] | no change |
1 , tương tự như xử lý filter ((), trong trường hợp đơn giản nhất, 2to3 sẽ sử dụng một hàm list (() để đóng gói map (() gọi ▽. 2 , Đối với ngữ pháp đặc biệt map ((None, …) tương tự như filter ((None, …) 2to3 sẽ chuyển đổi nó thành một gọi giá trị tương đương sử dụng list (() 3, nếu tham số đầu tiên của map () là hàm lambda, 2to3 sẽ chuyển đổi nó thành phân giải danh sách. 4, không cần thay đổi vòng for đi qua toàn bộ chuỗi. 5 Một lần nữa, không cần sửa đổi ở đây, bởi vì phân tích danh sách sẽ đi qua toàn bộ chuỗi, và nó sẽ hoạt động bình thường ngay cả khi map () trả về giá trị là iterator thay vì danh sách.
Trong Python 3, hàm reduce ((() đã được gỡ bỏ khỏi namespace toàn cầu, nó hiện được đặt trong mô-đun fucntools.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | reduce(a, b, c) | from functools import reduce reduce(a, b, c) |
Python 2 có một hàm toàn cầu gọi là apply (), nó sử dụng một hàm f và một danh sách[a, b, c] là một tham số, trả về f ((a, b, c) . Bạn cũng có thể gọi trực tiếp hàm này và thêm một dấu sao (((*Trong Python 3, chức năng apply ((() không còn tồn tại nữa; phải sử dụng ký hiệu ký hiệu sao.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | apply(a_function, a_list_of_args) | a_function(*a_list_of_args) |
| ② | apply(a_function, a_list_of_args, a_dictionary_of_named_args) | a_function(*a_list_of_args,**a_dictionary_of_named_args) |
| ③ | apply(a_function, a_list_of_args+ z) | a_function(*a_list_of_args+ z) |
| ④ | apply(aModule.a_function, a_list_of_args) | aModule.a_function(*a_list_of_args) |
1, dạng đơn giản nhất, có thể được thực hiện thông qua một danh sách các tham số (như[a, b, c]) trước khi thêm một ký hiệu sao để gọi hàm。 điều này tương đương với hàm apply ((() trong Python 2。 Trong Python 2, hàm apply ((() thực sự có thể có 3 tham số: một hàm, một danh sách tham số, và một danh mục tham số tên từ điển (((dictionary of named arguments)). Trong Python 3, bạn có thể thêm một dấu sao vào trước danh sách tham số (((), thêm hai ký hiệu sao trước tham số tên từ điển ((**Các nhà nghiên cứu cho rằng: 3, operator + được sử dụng ở đây như là một chức năng của danh sách kết nối, nó có ưu tiên cao hơn operator, vì vậy không cần thêm dấu ngoặc kép xung quanh a_list_of_args + z. 4 , kịch bản 2to3 đủ thông minh để chuyển đổi các cuộc gọi phức tạp của apply (), bao gồm cả các hàm trong mô-đun nhập khẩu.
Trong Python 2, bạn có thể sử dụng hàm intern (()) để giới hạn () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () ()
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | intern(aString) | sys.intern(aString) |
Giống như câu lệnh print trở thành một hàm trong Python 3, câu lệnh exec cũng vậy. Các hàm .exec () sử dụng một chuỗi chứa bất kỳ mã Python nào làm tham số, sau đó thực hiện nó như thể thực hiện câu lệnh hoặc biểu thức. .exec () tương tự như eval () nhưng mạnh hơn và tinh tế hơn. .eval () chỉ có thể thực hiện một biểu thức đơn lẻ, nhưng .exec () có thể thực hiện nhiều câu lệnh, nhập khẩu () và tuyên bố hàm.
| Notes | Python 2 | Python 3 |
|---|
|①|exec codeString|exec(codeString) |②|exec codeString in a_global_namespace|exec(codeString, a_global_namespace)| |③|exec codeString in a_global_namespace, a_local_namespace|exec(codeString, a_global_namespace,a_local_namespace)| 1, ở dạng đơn giản nhất, bởi vì exec (() bây giờ là một hàm, chứ không phải là một câu lệnh, 2to3 sẽ bao quanh đoạn mã dạng chuỗi này bằng dấu ngoặc kép. 2 , câu lệnh exec trong Python 2 có thể chỉ định một namespace, và mã sẽ được thực hiện trong không gian riêng tư này bao gồm các đối tượng toàn cầu. Python 3 cũng có chức năng như vậy; bạn chỉ cần truyền tên này như là tham số thứ hai cho hàm exec (). 3, điều kỳ diệu hơn nữa là, câu lệnh exec trong Python 2 cũng có thể chỉ định một namespace địa phương (ví dụ như biến được tuyên bố trong một hàm). Trong Python 3, hàm exec () cũng có chức năng như vậy.
Giống như các câu lệnh exec trước đó, câu lệnh execfile trong Python 2 cũng có thể sử dụng các chuỗi như khi thực thi mã Python. Trong Python 3, câu lệnh execfile đã bị loại bỏ. Nếu bạn thực sự muốn thực thi mã Python trong một tệp nhưng bạn không muốn nhập nó, bạn có thể mở tệp này, đọc nội dung của nó, và gọi hàm compile () toàn cầu để ép trình biên dịch Python biên dịch mã, và gọi hàm exec () mới.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | execfile(‘a_filename’) | exec(compile(open(‘a_filename’).read(),‘a_filename’,‘exec’)) |
Trong Python 2, để có thể biểu thị một chuỗi đối tượng bất kỳ, có một cách để gói đối tượng trong dấu ngoặc kép ((nhưxTrong Python 3, khả năng này vẫn tồn tại, nhưng bạn không thể sử dụng dấu ngoặc kép để có được chuỗi này nữa. Bạn cần sử dụng hàm toàn cầu repr ((() }}.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | `x` | repr(x) |
| ② | `‘PapayaWhip’ + `2`` | repr(‘PapayaWhip’+ repr(2)) |
Từ Python 2 đến Python 3, ngữ pháp để nắm bắt các trường hợp bất thường đã thay đổi một chút.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | try: import mymodule except ImportError, e pass |
try: import mymodule except ImportError as e: pass |
| ② | try: import mymodule except (RuntimeError, ImportError), e pass |
try: import mymodule except (RuntimeError, ImportError) as e: pass |
| ③ | try: import mymodule except ImportError: pass |
no change |
| ④ | try: import mymodule except: pass |
no change |
1, Python 3 sử dụng một từ khóa mới, as。 so với Python 2 để thêm dấu phẩy sau kiểu ngoại lệ. 2, từ khóa as cũng có thể được sử dụng trong trường hợp bắt nhiều loại bất thường cùng một lúc. 3, Nếu bạn bắt được một ngoại lệ, nhưng không quan tâm đến việc truy cập vào các đối tượng ngoại lệ, thì ngữ pháp của Python 2 và Python 3 là giống nhau. 4, tương tự như vậy, nếu bạn sử dụng một phương pháp bảo hiểm ((fallback) để bắt tất cả các trường hợp ngoại lệ, thì ngữ pháp của Python 2 và Python 3 sẽ giống nhau. 5. Khi nhập mô-đun (hoặc hầu hết các trường hợp khác), bạn hoàn toàn không nên sử dụng phương pháp này (gọi là fallback trên). Nếu không, chương trình có thể bị bắt gặp các trường hợp ngoại lệ như KeyboardInterrupt (nếu người dùng nhấn Ctrl-C để ngắt chương trình), làm cho việc khởi động trở nên khó khăn hơn.
Trong Python 3, có những thay đổi nhỏ trong ngữ pháp để loại bỏ các ngoại lệ tùy chỉnh.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | raise MyException | unchanged |
| ② | raise MyException,‘error message’ | raise MyException(‘error message’) |
| ③ | raise MyException,‘error message’, a_traceback | raise MyException(‘errormessage’).with_traceback(a_traceback) |
| ④ | raise ‘error message’ | unsupported |
1, loại bỏ ngoại lệ mà không có thông báo lỗi tùy chỉnh của người dùng, trong dạng đơn giản nhất này, ngữ pháp không thay đổi. Python 2 sử dụng một dấu phẩy để phân biệt loại ngoại lệ và thông tin lỗi; Python 3 truyền thông tin lỗi cho loại ngoại lệ như là tham số. Python 2 hỗ trợ một ngữ pháp phức tạp hơn để đưa ra một trường hợp ngoại lệ với dấu vết của người dùng. Trong Python 3 bạn cũng có thể làm điều này, nhưng ngữ pháp hoàn toàn khác. Trong Python 2, bạn có thể ném một ngoại lệ không có loại ngoại lệ, chỉ có một thông báo ngoại lệ. Trong Python 3, hình thức này không còn được hỗ trợ. 2to3 sẽ cảnh báo bạn rằng nó không thể tự động sửa lỗi này.
Trong Python 2, trình tạo có một phương thức throw (). Khi gọi a_generator.throw (), nó sẽ đưa ra một ngoại lệ khi trình tạo bị tạm ngưng và trả về giá trị tiếp theo được lấy từ hàm trình tạo. Trong Python 3, tính năng này vẫn có sẵn, nhưng có một cách thức ngữ pháp hơi khác.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | a_generator.throw(MyException) | no change |
| ② | a_generator.throw(MyException,‘error message’) | a_generator.throw(MyException(‘error message’)) |
| ③ | a_generator.throw(‘error message’) | unsupported |
Trong dạng đơn giản nhất, trình tạo sẽ đưa ra các ngoại lệ mà không có thông báo lỗi tùy chỉnh của người dùng. Trong trường hợp này, không có thay đổi về ngữ pháp từ Python 2 đến Python 3. 2. Nếu trình tạo phát ra một ngoại lệ với thông báo lỗi tùy chỉnh của người dùng, bạn cần chuyển chuỗi thông báo lỗi này cho lớp ngoại lệ để thực hiện nó. Python 3 không hỗ trợ ngữ pháp này, và 2to3 sẽ hiển thị một thông báo cảnh báo cho bạn biết bạn cần phải sửa lỗi này bằng tay.
Trong Python 2, có hai cách để có được số trong một phạm vi nhất định: range ((), trả về một danh sách, và range ((), trả về một iterator. Trong Python 3, range (() trả về iterator, xrange (()) không còn tồn tại.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | xrange(10) | range(10) |
| ② | a_list = range(10) | a_list = list(range(10)) |
| ③ | [i for iin xrange(10)] | [i for iin range(10)] |
| ④ | for i in range(10): | no change |
| ⑤ | sum(range(10)) | no change |
1, trong trường hợp đơn giản nhất, 2to3 sẽ chỉ đơn giản chuyển đổi xrange () thành range () [2]. 2, Nếu mã Python 2 của bạn sử dụng range (), 2to3 không biết bạn có cần một danh sách hay không, hoặc một trình tự cũng không. Vì sự thận trọng, 2to3 có thể báo lỗi, sau đó sử dụng list () để buộc giá trị trả về của range () chuyển đổi thành loại danh sách. 3, nếu trong phân tích danh sách có hàm xrange (), không cần thiết phải chuyển giá trị trả về của nó thành một danh sách, bởi vì phân tích danh sách cũng có hiệu quả đối với iterator. 4 , tương tự, vòng lặp for cũng có thể hoạt động trên iterator, vì vậy không thay đổi bất cứ điều gì ở đây. 5 , hàm sum ((() có thể hoạt động trên trình nhân, vì vậy 2to3 cũng không thay đổi ở đây. Giống như cách trả về giá trị là view ((view) và không còn là một danh sách, điều này cũng áp dụng cho min (((), max (((), sum (((), list (((), tuple (((), set (((), sorted (((), any (((), all (())
Python 2 có hai hàm toàn cầu được sử dụng để yêu cầu người dùng nhập vào dòng lệnh. Đầu tiên được gọi là input (((), nó chờ người dùng nhập một biểu thức Python ((( và sau đó trả về kết quả). Thứ hai được gọi là raw_input (((), người dùng nhập gì nó sẽ trả về gì.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | raw_input() | input() |
| ② | raw_input(‘prompt’) | input(‘prompt’) |
| ③ | input() | eval(input()) |
1, dạng đơn giản nhất, raw_input ((() được thay thế thành input ((() }}. 2, Trong Python 2, hàm raw_input (()) có thể chỉ định một dấu hiệu như là một tham số. Trong Python 3, chức năng này được giữ lại. 3, Nếu bạn thực sự muốn yêu cầu người dùng nhập vào một biểu thức Python, bạn có thể tính toán kết quả bằng cách gọi hàm input () và chuyển giá trị trả về cho eval () [2].
Trong Python 2, mã trong hàm có thể truy cập vào các thuộc tính đặc biệt của hàm. Trong Python 3, các thuộc tính đặc biệt này đã được đặt tên lại để phù hợp.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | a_function.func_name | a_function._name_ |
| ② | a_function.func_doc | a_function._doc_ |
| ③ | a_function.func_defaults | a_function._defaults_ |
| ④ | a_function.func_dict | a_function._dict_ |
| ⑤ | a_function.func_closure | a_function._closure_ |
| ⑥ | a_function.func_globals | a_function._globals_ |
| ⑦ | a_function.func_code | a_function._code_ |
1、name thuộc tính ((originalfunc_name) chứa tên của hàm。 2、doc thuộc tính ((originalfuncdoc) chứa chuỗi tài liệu mà bạn định nghĩa trong mã nguồn của hàm ((docstring) 3、defaultsattribute ((originalfunc_defaults) là một nhóm nguyên tố lưu các giá trị mặc định của tham số. 4、dictattribute ((originalfunc_dict) là một namespace hỗ trợ các thuộc tính của các hàm tùy ý. 5、closureattribute ((originalfunc_closure) là một nhóm các đối tượng cell, nó chứa hàm bị ràng buộc với biến tự do ((free variable)). 6、globals thuộc tính ((func_globals gốc) là một tham chiếu đến namespace toàn cầu của mô-đun, hàm được định nghĩa trong namespace này. 7、code thuộc tính ((originalfunc_code) là một đối tượng mã, biểu thị các hàm sau khi biên dịch.
Trong Python 2, đối tượng tập tin có phương thức xreadlines () mà trả về một hàm lặp, đọc một dòng tập tin một lần. Điều này đặc biệt hữu ích trong vòng lặp for. Thực tế, các phiên bản Python 2 sau đó đã thêm tính năng này vào đối tượng tập tin.
Trong Python 3, phương pháp xreadlines () không còn được sử dụng nữa. 2to3 có thể giải quyết các trường hợp đơn giản, nhưng một số trường hợp biên cần sự can thiệp của con người.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | for line in a_file.xreadlines(): | for line in a_file: |
| ② | for line in a_file.xreadlines(5): | no change (broken) |
1, nếu bạn gọi xreadlines mà trước đây không có tham số ((), 2to3 sẽ chuyển đổi nó thành đối tượng file chính nó. Trong Python 3, mã sau chuyển đổi này có thể thực hiện công việc tương tự như trước: đọc một dòng file một lần, sau đó thực hiện for vòng lặp for vòng lặp. Nếu bạn đã sử dụng một tham số ((số dòng đọc mỗi lần) để gọi xreadlines ((), 2to3 không thể thực hiện chuyển đổi từ Python 2 sang Python 3 cho bạn, mã của bạn sẽ thất bại theo cách này: AttributeError: ‘_io.TextIOWrapper’ object has no attribute ‘xreadlines’. Bạn có thể tự thay đổi xreadlines thành readlines để code có thể hoạt động trong Python 3.
Trong Python 2, bạn có thể định nghĩa hàm lambda ẩn danh (anonymous lambda function) để hàm này thực sự có thể nhận được nhiều tham số bằng cách chỉ định số phần tử của mô-tô là tham số. Trên thực tế, trình diễn Python 2 giải mã mô-tô này thành các tham số được đặt tên (named arguments), sau đó bạn có thể trích dẫn chúng trong hàm lambda (thông qua tên). Trong Python 3, bạn vẫn có thể truyền một mô-tô làm tham số của hàm lambda, nhưng trình diễn Python sẽ không phân tích nó thành tham số được đặt tên. Bạn cần tham khảo mỗi tham số thông qua chỉ mục vị trí (positional index).
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | lambda (x,): x+ f(x) | lambda x1: x1[0]+f(x1[0]) |
| ② | lambda (x, y): x+f(y) | lambda x_y: x_y[0]+f(x_y[1]) |
| ③ | lambda (x,(y,z)): x+ y+ z | lambda x_y_z: x_y_z[0]+x_y_z[1][0]+ x_y_z[1][1] |
| ④ | lambda x, y, z: x+y + z | unchanged |
1, nếu bạn đã định nghĩa một hàm lambda, nó sử dụng một hàm chứa một phần tử như là tham số, trong Python 3, nó sẽ được chuyển thành một hàm chứa đến x1[Hàm lambda được trích dẫn của 0]。x1 được tự động tạo ra bởi kịch bản 2to3 dựa trên các tham số đặt tên trong mô-tô gốc。 2, sử dụng một nhóm gồm hai phần tử ((x, y) làm tham số, hàm lambda được chuyển thành x_y, nó có hai tham số vị trí, x_y[0] và x_y[1]。 Các kịch bản 2 đến 3 thậm chí có thể xử lý hàm lambda của hàm sử dụng tham số đặt tên mô hình làm tham số. Mã kết quả có thể hơi khó đọc, nhưng nó hoạt động giống như mã gốc trong Python 3 và Python 2. Bạn có thể định nghĩa hàm lambda sử dụng nhiều tham số. Nếu không có dấu ngoặc kép bao quanh tham số, Python 2 sẽ coi nó là một hàm lambda có nhiều tham số; trong hàm lambda này, bạn tham khảo các tham số này bằng tên, giống như trong các loại hàm khác.
Trong Python 2, các phương thức lớp có thể truy cập vào các đối tượng lớp (class object) để xác định chúng, cũng có thể truy cập vào các đối tượng phương thức (method object) chính nó. im_self là đối tượng thực thể của lớp; im_func là đối tượng hàm, im_class là lớp chính nó. Trong Python 3, các thuộc tính này được đặt tên lại để tuân theo các quy định đặt tên cho các thuộc tính khác.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | aClassInstance.aClassMethod.im_func | aClassInstance.aClassMethod._func_ |
| ② | aClassInstance.aClassMethod.im_self | aClassInstance.aClassMethod._self_ |
| ③ | aClassInstance.aClassMethod.im_class | aClassInstance.aClassMethod._self_._class_ |
Trong Python 2, bạn có thể tạo ra các lớp riêng của mình và cho phép chúng được sử dụng trong một Boolean context. Ví dụ, bạn có thể thực tế hóa lớp và sử dụng đối tượng thực tế này trong một câu if. Để thực hiện điều này, bạn định nghĩa một cụ thểnonzero_Phương thức _(), trả về True hoặc False, được gọi khi đối tượng instance nằm trong một context trên boolean. Trong Python 3, bạn vẫn có thể thực hiện cùng một chức năng, nhưng tên của phương thức đặc biệt này đã biến thànhbool__()。
| Notes | Python 2 | Python 3 |
|---|
|①|class A:
def nonzero(self):
pass|class A:
def bool(self):
pass
|②|class A:
def nonzero(self, x, y):
pass|no change|
1, Python 3 sẽ gọi khi sử dụng một đối tượng lớp trong ngữ cảnh trên Booleanbool_Không phải là.nonzero()。
Tuy nhiên, nếu bạn có một định nghĩa sử dụng hai tham sốnonzero__() phương thức, kịch bản 2to3 sẽ giả định rằng phương thức mà bạn định nghĩa có mục đích khác, do đó không thay đổi mã.
Giữa Python 2 và Python 3, ngữ pháp định nghĩa số tám chữ số (octal) có một sự thay đổi nhỏ.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | x = 0755 | x = 0o755 |
Vì long integer và integer đã được tích hợp lại với nhau, hằng số sys.maxint không còn chính xác nữa. Nhưng vì giá trị này vẫn hữu ích để phát hiện khả năng của một nền tảng cụ thể, nó đã được Python 3 giữ lại và được đổi tên thành sys.maxsize.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | from sys importmaxint | from sys importmaxsize |
| ② | a_function(sys.maxint) | a_function(sys.maxsize) |
1, maxint trở thành maxsize. 2, tất cả các sys.maxint sẽ trở thành sys.maxsize.
Trong Python 2, bạn có thể sử dụng hàm toàn cầu callable ((() để kiểm tra xem một đối tượng có thể được gọi là ((callable, ví dụ như hàm)) không. Trong Python 3, hàm toàn cầu này đã bị loại bỏ. Để kiểm tra xem một đối tượng có thể được gọi hay không, bạn có thể kiểm tra các phương thức đặc biệt__call_Sự tồn tại của …
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | callable(anything) | hasattr(anything,’_call_’) |
Trong Python 2, hàm toàn cầu zip ((() có thể sử dụng bất kỳ chuỗi nào như tham số, nó trả về một danh sách gồm các mảng. Mảng đầu tiên chứa các phần tử đầu tiên của mỗi chuỗi; mảng thứ hai chứa các phần tử thứ hai của mỗi chuỗi; theo lượt đi. Trong Python 3, zip ((() trả về một nhân tố, chứ không phải là danh sách.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | zip(a, b, c) | list(zip(a, b, c)) |
| ② | d.join(zip(a, b, c)) | no change |
Trong dạng đơn giản nhất, bạn có thể gọi hàm list () đóng gói zip () để khôi phục các giá trị trả về của hàm zip () trước khi hàm list () đi qua hàm iterator mà hàm zip () trả về, và sau đó trả về kết quả của list. Trong một môi trường ngữ cảnh đã đi qua tất cả các thành phần của chuỗi (ví dụ như cách gọi join () ở đây), zip () trả về trình tự sẽ hoạt động bình thường. Các kịch bản 2to3 sẽ phát hiện những trường hợp này và không thay đổi mã của bạn.
Trong Python 2, StandardError là lớp cơ sở của tất cả các trường hợp ngoại lệ bên trong ngoại trừ StopIteration, GeneratorExit, KeyboardInterrupt, và SystemExit. Trong Python 3, StandardError đã được loại bỏ và thay thế bằng Exception.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | x =StandardError() | x =Exception() |
| ② | x =StandardError(a, b, c) | x =Exception(a, b, c) |
Các hằng số khác nhau trong mô-đun types giúp bạn quyết định loại của một đối tượng. Trong Python 2, nó chứa hằng số đại diện cho tất cả các loại dữ liệu cơ bản, chẳng hạn như dict và int. Trong Python 3, các hằng số này đã được loại bỏ. Chỉ cần sử dụng tên của loại cơ bản để thay thế.
| Notes | Python 2 | Python 3 |
|---|---|---|
| types.UnicodeType | str | |
| types.StringType | bytes | |
| types.DictType | dict | |
| types.IntType | int | |
| types.LongType | int | |
| types.ListType | list | |
| types.NoneType | type(None) | |
| types.BooleanType | bool | |
| types.BufferType | memoryview | |
| types.ClassType | type | |
| types.ComplexType | complex | |
| types.EllipsisType | type(Ellipsis) | |
| types.FloatType | float | |
| types.ObjectType | object | |
| types.NotImplementedType | type(NotImplemented) | |
| types.SliceType | slice | |
| types.TupleType | tuple | |
| types.TypeType | type | |
| types.XRangeType | range |
Types.StringType được biểu diễn bằng byte, chứ không phải là str, bởi vì trong Python 2, string thực sự chỉ là một chuỗi byte được mã hóa bằng một số ký tự.
isinstance() hàm kiểm tra xem một đối tượng là một instance của một class hoặc type nào đó. Trong Python 2, bạn có thể chuyển một mảng gồm các type (các loại) cho instance (các loại), và nếu đối tượng đó là bất kỳ loại nào trong mảng, hàm sẽ trả về True. Trong Python 3, bạn vẫn có thể làm điều đó, nhưng không nên sử dụng một loại để chuyển hai lần như một tham số.
| Notes | Python 2 | Python 3 |
|---|---|---|
| isinstance(x,(int,float,int)) | isinstance(x,(int,float)) |
Python 2 có hai loại chuỗi: chuỗi được mã hóa bằng Unicode và chuỗi không được mã hóa bằng Unicode. Nhưng thực tế có một loại khác, đó là basestring. Nó là một loại dữ liệu trừu tượng, là siêu lớp của str và unicode. Nó không thể được gọi trực tiếp hoặc thực tế hóa, nhưng bạn có thể sử dụng nó như một tham số của instance () để kiểm tra xem một đối tượng là một chuỗi Unicode hay một chuỗi không Unicode.
| Notes | Python 2 | Python 3 |
|---|---|---|
| isinstance(x, basestring) | isinstance(x, str) |
Python 2.3 đã giới thiệu mô-đun itertools, nó xác định các biến thể của hàm toàn cầu zip (), map (), filter (), và các biến thể này