avatar of 发明者量化-小小梦 发明者量化-小小梦
tập trung vào tin nhắn riêng tư
4
tập trung vào
1271
Người theo dõi

Những thay đổi giữa Python 2.x.x và Python 3.x.x & Cách chuyển đổi Python 2.x.x sang Python 3.x.x

Được tạo ra trong: 2016-10-09 12:36:49, cập nhật trên: 2017-10-11 10:18:05
comments   2
hits   5325

Phân biệt và thay đổi ngữ pháp của python2 và python3

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.

  • #### print câu

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()
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.

  • #### Dãy ký tự Unicode

Python 2 có hai loại chuỗi:Dãy ký tự UnicodeDã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.

  • #### Hàm toàn cầu (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)
  • #### long dài

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.

  • #### <> So sánh toán tử

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.

  • #### Phương pháp từ điển has_key()

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

  • #### Phương thức lớp từ điển trả về danh sách

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 (().

  • #### Các mô-đun được đổi tên hoặc tổ chức lại

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.

  • http Trong Python 3, một số mô-đun HTTP liên quan được kết hợp thành một gói riêng biệt, http.
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

  • urllib Python 2 có một số mô-đun để phân tích, mã hóa và lấy URL, nhưng các mô-đun này chồng lên nhau giống như một cái móc chuột. Trong Python 3, các mô-đun này được cấu trúc lại và kết hợp thành một gói riêng biệt, urllib.
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())
  • dbm Tất cả các bản sao DBM bây giờ nằm trong một gói riêng, dbm. Nếu bạn cần một biến thể cụ thể của chúng, chẳng hạn như GNUDBM, bạn có thể nhập các mô-đun phù hợp trong gói dbm.
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
  • xmlrpc XML-RPC là một phương pháp hạng nhẹ để thực hiện các cuộc gọi RPC từ xa thông qua giao thức HTTP. Một số thư viện thực hiện của khách hàng XML-RPC và máy chủ XML-RPC hiện đã được kết hợp thành một gói riêng biệt, xmlrpc.
Notes Python 2 Python 3
import xmlrpclib import xmlrpc.client
import DocXMLRPCServer
import SimpleXMLRPCServer
import xmlrpc.server
  • #### Các mô-đun khác
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.

  • Tỷ lệ nhập khẩu trong gói

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.

  • #### Phương pháp nhân nét (next)

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

  • #### Filter hàm toàn cầu

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 đó.

  • #### Global Function Map (Tạm dịch: Bản đồ chức năng toàn cầu)

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.

  • #### Hàm toàn cầu reduce ()

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)
  • #### Hình thức global apply ()

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.

  • #### Hàm toàn cầu intern ())

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)
  • #### exec câu lệnh

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.

  • #### execfile câu lệnh

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’))
  • #### repr (được trích dẫn)

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))
  1. Hãy nhớ rằng, x có thể là bất cứ thứ gì: một lớp, một hàm, một mô-đun, một kiểu dữ liệu cơ bản, v.v. 2, trong Python 2, dấu ngoặc kép có thể được lắp đặt, dẫn đến biểu thức khó hiểu này (nhưng hiệu quả). 2to3 đủ thông minh để chuyển đổi cuộc gọi lắp đặt này thành hàm repr ().
  • #### try…except câu nói

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.

  • #### Câu nói raise

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.

  • #### Phương pháp throw của trình tạo

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.

  • #### Hàm toàn cầu xrange

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

  • #### Hàm toàn cầu raw_input ()) và input ())

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

  • #### thuộc tính của hàm func_*

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.

  • #### Phương pháp I/O xreadlines

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.

  • #### Hàm lambda sử dụng nguyên tố thay vì nhiều tham số

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.

  • #### Thuộc tính đặc biệt của phương thứ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_
  • #### __nonzero_Phương pháp đặc biệt

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

  • #### Loại octa-dimensional

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
  • #### sys.maxint

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.

  • #### Hàm toàn cầu callable ())

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_’)
  • #### Hàm toàn cầu (zip)

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.

  • #### StandardError bất thường

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)
  • #### Hằng số trong mô-đun types

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

  • #### Hình thức hàm toàn cầu

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))
  • #### kiểu dữ liệu basestring

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)
  • #### Mô-đun itertools

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