Thứ tư, 17/05/2017 | 00:00 GMT+7

Cách chuyển mã Python 2 sang Python 3

Python được phát triển vào cuối những năm 1980 và xuất bản lần đầu tiên vào năm 1991. Với cái tên được lấy cảm hứng từ group hài Monty Python của Anh, Python được hình thành như một sự kế thừa cho ngôn ngữ lập trình ABC có mục đích chung. Trong lần lặp đầu tiên, Python đã bao gồm xử lý ngoại lệ, các hàmcác lớp có tính kế thừa .

Hướng dẫn này sẽ hướng dẫn bạn các phương pháp hay nhất và những điều cần cân nhắc khi chuyển mã từ Python 2 sang Python 3 và liệu bạn có nên duy trì mã tương thích với cả hai version hay không.

Lý lịch

Python 2 được xuất bản vào năm 2000, báo hiệu một quá trình phát triển ngôn ngữ toàn diện và minh bạch hơn. Nó bao gồm nhiều tính năng lập trình hơn và thêm nhiều tính năng hơn trong suốt quá trình phát triển của nó.

Python 3 được coi là tương lai của Python và là version của ngôn ngữ hiện đang được phát triển. Được phát hành vào cuối năm 2008, Python 3 đã giải quyết và sửa đổi các lỗi thiết kế nội tại. Tuy nhiên, việc áp dụng Python 3 còn chậm do ngôn ngữ này không tương thích ngược với Python 2.

Python 2.7 được xuất bản vào năm 2010 là version cuối cùng trong số 2.x. Mục đích đằng sau Python 2.7 là giúp user Python 2.x chuyển các tính năng sang Python 3 dễ dàng hơn bằng cách cung cấp một số thước đo về khả năng tương thích giữa cả hai.

Bạn có thể tìm hiểu thêm về các version Python và chọn version nào để sử dụng bằng cách đọc hướng dẫn của ta “ Python 2 so với Python 3: Cân nhắc thực tế ”.

Bắt đầu với Python 2.7

Để chuyển sang Python 3 hoặc hỗ trợ đồng thời Python 2 và Python 3, bạn nên đảm bảo mã Python 2 của bạn hoàn toàn tương thích với Python 2.7.

Nhiều nhà phát triển đã và đang làm việc độc quyền với mã Python 2.7, nhưng điều quan trọng là phải xác nhận bất kỳ thứ gì chỉ được hỗ trợ bởi các version trước đó đều hoạt động bình thường với Python 2.7 và phù hợp với kiểu Python 2.7.

Đảm bảo rằng mã của bạn bằng Python 2.7 là đặc biệt quan trọng vì đây là version Python 2 duy nhất vẫn đang được duy trì và nhận các bản sửa lỗi. Nếu bạn đang làm việc trên version Python 2 cũ hơn, bạn sẽ phải giải quyết các vấn đề bạn gặp phải với mã không còn được hỗ trợ và không còn nhận buxfix nữa.

Ngoài ra, một số công cụ giúp bạn chuyển mã dễ dàng hơn, chẳng hạn như gói Pylint tìm lỗi lập trình, không được hỗ trợ bởi các version Python cũ hơn 2.7.

Điều quan trọng cần lưu ý là mặc dù Python 2.7 hiện vẫn đang được hỗ trợ và duy trì, nhưng cuối cùng nó sẽ hết hạn sử dụng. PEP 373 nêu chi tiết về lịch trình phát hành Python 2.7 và tại thời điểm viết bài, đánh dấu ngày kết thúc của nó là năm 2020.

Kiểm tra vùng phủ sóng

Tạo các trường hợp thử nghiệm có thể là một phần quan trọng của công việc được thực hiện để di chuyển mã Python 2 sang Python 3. Nếu bạn đang duy trì nhiều version Python, bạn cũng nên đảm bảo bộ thử nghiệm của bạn có phạm vi tổng thể tốt đảm bảo rằng mỗi version vẫn hoạt động như mong đợi.

Là một phần của thử nghiệm của bạn, bạn có thể thêm các trường hợp Python tương tác với docstrings của tất cả các bạn chức năng, phương pháp, các lớp học, và module và sau đó sử dụng được xây dựng trong doctest module để xác minh họ làm việc như thể hiện.

Cùng với doctest , bạn có thể sử dụng coverage.py gói để theo dõi coverages kiểm tra đơn vị. Công cụ này sẽ theo dõi chương trình của bạn và lưu ý phần nào của mã đã được thực thi và phần nào có thể đã được thực thi nhưng không. coverage.py có thể in báo cáo ra dòng lệnh hoặc cung cấp kết quả HTML. Nó thường được sử dụng để đo lường hiệu quả của các thử nghiệm, cho bạn biết phần nào của mã đang được thực thi bằng thử nghiệm và phần nào không.

Lưu ý bạn không nhắm đến phạm vi kiểm tra 100% - bạn muốn đảm bảo bạn che bất kỳ mã nào gây nhầm lẫn hoặc bất thường. Đối với các phương pháp hay nhất, bạn nên nhắm đến mức độ bao phủ 80%.

Tìm hiểu về sự khác biệt giữa Python 2 và Python 3

Tìm hiểu về sự khác biệt giữa Python 2 và Python 3 sẽ đảm bảo bạn có thể tận dụng các tính năng mới có sẵn hoặc sẽ có sẵn trong Python 3.

Hướng dẫn của ta về “ Python 2 so với Python 3 ” đề cập đến một số điểm khác biệt chính giữa hai version và bạn có thể xem lại tài liệu Python chính thức để biết thêm chi tiết.

Khi bắt đầu với chuyển và di chuyển, có một số thay đổi về cú pháp mà bạn có thể thực hiện ngay bây giờ.

print

Câu print của Python 2 đã thay đổi thành hàm print() trong Python 3.

Python 2 Python 3
print "Hello, World!" print("Hello, World!")

exec

Các exec tuyên bố của Python 2 đã thay đổi thành một chức năng cho phép người dân local rõ ràng và globals bằng Python 3.

Python 2 Python 3
exec code exec(code)
exec code in globals exec(code, globals)
exec code in (globals, locals) exec(code, globals, locals)

///

Python 2 thực hiện phân chia tầng với toán tử / , Python 3 đã giới thiệu // để phân chia tầng.

Python 2 Python 3
5 / 2 = 2 5 / 2 = 2.5
5 // 2 = 2

Để sử dụng các toán tử này trong Python 2, hãy nhập division từ module __future__ :

from __future__ import division 

Đọc thêm về phép chia với số nguyên .

raise

Trong Python 3, việc nâng cao các ngoại lệ với các đối số yêu cầu dấu ngoặc đơn và không thể sử dụng chuỗi làm ngoại lệ.

Python 2 Python 3
raise Exception, args raise Exception
raise Exception(args)
raise Exception, args, traceback raise Exception(args).with_traceback(traceback)
raise "Error" raise Exception("Error")

except

Trong Python 2, rất khó để liệt kê nhiều ngoại lệ, nhưng điều đó đã thay đổi trong Python 3.

Lưu ý as được sử dụng rõ ràng với except trong Python 3

Python 2 Python 3
except Exception, variable: except AnException as variable:
except (OneException, TwoException) as variable:

def

Trong Python 2, các hàm có thể nhận theo chuỗi như bộ dữ liệu hoặc danh sách . Trong Python 3, việc extract này đã bị loại bỏ.

Python 2 Python 3
def function(arg1, (x, y)): def function(arg1, x_y): x, y = x_y

expr

Cú pháp backtick của Python 2 không còn tồn tại. Sử dụng repr() hoặc str.format() trong Python 3.

Python 2 Python 3
x = `355/113` x = repr(355/113):

Định dạng chuỗi

Cú pháp định dạng chuỗi đã thay đổi từ Python 2 thành Python 3.

Python 2 Python 3
"%d %s" % (i, s) "{} {}".format(i, s)
"%d/%d=%f" % (355, 113, 355/113) "{:d}/{:d}={:f}".format(355, 113, 355/113)

Tìm hiểucách sử dụng bộ định dạng chuỗi trong Python 3 .

class

Không cần phải nêu object trong Python 3.

Python 2

class MyClass(object):     pass 

Python 3

class MyClass:     pass 

Trong Python 3, metaclass được đặt bằng từ khóa metaclass .

Python 2

class MyClass:     __metaclass__ = MyMeta 
class MyClass(MyBase):     __metaclass__ = MyMeta 

Python 3

class MyClass(metaclass=type):     pass 
class MyClass(MyBase, metaclass=MyMeta):      pass 

Cập nhật mã

Có hai công cụ chính mà bạn có thể sử dụng để tự động cập nhật mã của bạn lên Python 3 trong khi vẫn giữ nó tương thích với Python 2: tương laihiện đại hóa . Mỗi công cụ này hoạt động hơi khác nhau: future công việc future để làm cho các thành ngữ Python 3 và các phương pháp hay nhất tồn tại trong Python 2, trong khi việc modernize nhằm mục đích cho tập con Python 2/3 của Python sử dụng mô-đun Python six để cải thiện khả năng tương thích.

Sử dụng các công cụ này để xử lý các chi tiết của việc viết lại mã có thể giúp bạn xác định và sửa chữa các vấn đề tiềm ẩn và sự mơ hồ.

Bạn có thể chạy công cụ trên bộ công cụ độc nhất của bạn để kiểm tra và xác minh mã một cách trực quan và đảm bảo các bản sửa đổi tự động được thực hiện là chính xác. Khi các bài kiểm tra vượt qua, bạn có thể chuyển đổi mã của bạn .

Từ đây, bạn có thể cần phải thực hiện một số sửa đổi thủ công, đặc biệt là nhắm đến các thay đổi giữa Python 2 và 3 được lưu ý trong phần trên .

Tận dụng future , bạn nên xem xét thêm câu lệnh import này vào từng module Python 2.7 của bạn :

from __future__ import print_function, division, absolute_imports, unicode_literals 

Mặc dù điều này cũng sẽ dẫn đến việc viết lại, nhưng nó sẽ đảm bảo mã Python 2 của bạn phù hợp với cú pháp Python 3.

Cuối cùng, bạn có thể sử dụng gói pylint để xác định bất kỳ vấn đề tiềm ẩn nào khác trong mã. Gói này chứa hàng trăm luật riêng lẻ bao gồm nhiều vấn đề có thể xảy ra, bao gồm các luật hướng dẫn kiểu PEP 8 , cũng như các lỗi sử dụng.

Bạn có thể thấy rằng có một số cấu trúc trong mã của bạn có thể gây nhầm lẫn giữa pylint và các công cụ được sử dụng để di chuyển tự động. Nếu bạn không thể đơn giản hóa các cấu trúc này, bạn cần phải sử dụng các trường hợp đơn giản nhất.

Hội nhập liên tục

Nếu bạn định duy trì mã của bạn cho nhiều version Python, bạn cần phải cảnh giác về việc chạy và chạy lại bộ ứng dụng độc nhất của bạn thông qua tích hợp liên tục (thay vì thủ công) thường xuyên nhất có thể trên mã khi bạn phát triển nó .

Nếu bạn sử dụng gói six như một phần của bảo trì khả năng tương thích Python 2 và 3, bạn cần sử dụng nhiều môi trường cho thử nghiệm của bạn .

Một công cụ quản lý môi trường mà bạn có thể cân nhắc sử dụng là gói tox , vì nó sẽ kiểm tra lượt cài đặt gói của bạn với các version Python khác nhau, chạy thử nghiệm trong từng môi trường của bạn và hoạt động như một giao diện user cho các server Tích hợp liên tục.

Kết luận

Điều quan trọng cần lưu ý là khi sự chú ý của nhà phát triển và cộng đồng tập trung nhiều hơn vào Python 3, ngôn ngữ này sẽ trở nên tinh tế hơn và phù hợp với nhu cầu phát triển của các lập trình viên và sẽ ít hỗ trợ hơn cho Python 2.7. Nếu bạn quyết định duy trì các version cơ sở mã của bạn cho cả Python 2 và Python 3, bạn có thể gặp khó khăn ngày càng tăng với version cũ vì nó sẽ nhận được ít bản sửa lỗi hơn theo thời gian.

Cần xem xét các dự án đã chuyển Python 2 sang Python 3, bao gồm các nghiên cứu điển hình như Porting chardet sang Python 3 .


Tags:

Các tin liên quan

Cách chuyển mã Python 2 sang Python 3
2017-05-17
Cách sử dụng tính năng ghi log trong Python 3
2017-05-02
Cách gỡ lỗi Python bằng control panel tương tác
2017-04-27
Cách sử dụng trình gỡ lỗi Python
2017-04-25
Cách cài đặt Python 3 và thiết lập môi trường lập trình cục bộ trên CentOS 7
2017-04-20
Cách cài đặt Python 3 và thiết lập môi trường lập trình cục bộ trên Debian 8
2017-04-20
Cách cài đặt Python 3 và thiết lập môi trường lập trình cục bộ trên CentOS 7
2017-04-20
Cách áp dụng tính đa hình cho các lớp trong Python 3
2017-04-13
Hướng dẫn dự báo chuỗi thời gian với prophet bằng Python 3
2017-04-04
Hiểu các biến lớp và phiên bản trong Python 3
2017-03-27