Tôi nghĩ rằng tôi sẽ thêm một chút vào chiến lược được ủng hộ bởi câu trả lời của Wim - hãy lấy phiên bản Django phù hợp hoạt động trên cả 2.7 và 3.x trước - và phác thảo một số chiến thuật phù hợp với tôi.
Python 2.7 là nhóm thoát của bạn, cho đến khi bạn bóp cò trên 3.x
- bài kiểm tra của bạn nên chạy trên cả hai
- không sử dụng bất kỳ tính năng cụ thể 3.x nào, như chuỗi f
- đầu tiên là Python 3.x, sau đó chỉ sau Django 2.x không chạy trên 2.7
- bắt đầu sớm, đừng phân tích quá mức, nhưng tránh cách tiếp cận vụ nổ lớn
- tập tin theo tập tin lúc đầu
- bắt đầu với mã cấp thấp nhất, như thư viện tiện ích, mà bạn có bộ kiểm tra.
- nếu có thể, hãy cố gắng hợp nhất dần các thay đổi của bạn với các nhánh sản xuất 2.7 và giữ cho mã cổng 3.x của bạn được cập nhật với các thay đổi prod.
Phiên bản nhỏ nào của Django để bắt đầu?
Tiêu chí của tôi ở đây là việc di chuyển Django có thể tham gia khá nhiều (và thực sự đòi hỏi nhiều suy nghĩ hơn 2 => 3 công việc). Vì vậy, tôi sẽ chuyển sang bản 1.11 mới nhất và lớn nhất theo cách mà bạn đã cung cấp một số giá trị cho 2.7 người dùng của bạn. Có lẽ có một số lượng tốt khả năng tương thích trước 2.x trên 1.11 và bạn sẽ nhận được cảnh báo khấu hao 2.x của nó.
Phiên bản nhỏ nào của Python 3.x để bắt đầu?
Tốt nhất để xem xét tất cả các góc độ, chẳng hạn như tính khả dụng của libs bên thứ 3 của bạn, hỗ trợ từ bộ CI / devops và tính khả dụng trên hình ảnh hệ điều hành máy chủ đã chọn của bạn. Ví dụ, bạn luôn có thể cài đặt 3,8 và thử cài đặt pip của tệp.txt.txt của mình.
Tận dụng git (hoặc bất cứ thứ gì bạn sử dụng scm) và virtualenv .
- tách rời
requirement.txt
các tệp , nhưng ...
- nếu bạn có một repo dựa trên tệp, bạn có thể trỏ từng venv tại cùng một dòng mã với a
pip install -e <your directory>
. điều đó có nghĩa là, trong 2 thiết bị đầu cuối khác nhau, bạn có thể chạy 2,7 và 3.x so với cùng một (các) đơn vị khác nhau.
- bạn thậm chí có thể chạy các máy chủ Django 2.7 và 3.x cạnh nhau trên các cổng khác nhau và nói rằng Firefox và Chrome ở đó.
- cam kết thường xuyên (ít nhất là trên nhánh porting) và tìm hiểu về git bisect .
tận dụng 2to3
Có, nó sẽ phá vỡ mã 2.7 và Django nếu bạn để nó. Vì thế...
chạy nó trong chế độ xem trước hoặc đối với một tập tin duy nhất. xem những gì nó phá vỡ nhưng cũng thấy những gì nó đã làm đúng.
điều chỉnh nó để chỉ một số chuyển đổi nhất định không phá vỡ 2.7 hoặc Django. print x
=> print (x)
và except(Exception) as e
là 2 người không có trí tuệ.
Đây là những gì lệnh điều chỉnh của tôi trông giống như:
2to3 $tgt -w -f except -f raise -f next -f funcattrs -f print
- chạy nó từng tập tin cho đến khi bạn thực sự tự tin.
sử dụng sed hoặc awk thay vì trình chỉnh sửa của bạn để chuyển đổi hàng loạt.
Ưu điểm là, khi bạn nhận thức rõ hơn về mối quan tâm cụ thể của ứng dụng của mình, bạn có thể xây dựng một bộ thay đổi có thể chạy trên 1 tệp hoặc nhiều tệp và thực hiện hầu hết công việc mà không phá vỡ 2.7 hoặc Django. Áp dụng điều này sau khi vượt qua 2to3 phù hợp của bạn . Điều đó khiến bạn phải dọn dẹp dư thừa trong trình chỉnh sửa của mình và vượt qua các bài kiểm tra.
(tùy chọn) bắt đầu chạy màu đen trên mã 2.7.
màu đen là một trình định dạng mã, sử dụng Python 3 AST để chạy phân tích của nó. Nó không cố chạy mã, nhưng nó sẽ đánh dấu các lỗi cú pháp ngăn nó đến giai đoạn AST. Bạn sẽ phải làm việc một số pip cài đặt ma thuật toàn cầu để đến đó và bạn phải mua tính hữu dụng của màu đen.
Những người khác đã làm điều đó - học hỏi từ họ.
Nghe # 155 Các bước thực tế để chuyển sang Python 3 sẽ cung cấp cho bạn một số ý tưởng về công việc. Nhìn vào các liên kết hiển thị cho nó. Họ thích nói về động thái trên Instagram (?) Liên quan đến việc điều chỉnh dần dần việc chạy mã 2.7 thành cú pháp 3.x trên một cơ sở mã thông thường và trên cùng một nhánh git, cho đến ngày kéo.
Xem thêm Hướng dẫn chuyển đổi Python 3 bảo thủ
và Instagram giúp di chuyển mượt mà lên Python 3 - Ngăn xếp mới
Phần kết luận
Thời gian của bạn để Django 1.11 EOL (tháng 4 năm 2020) khá ngắn, vì vậy nếu bạn có hơn 2 tài nguyên dev để sử dụng, tôi sẽ xem xét thực hiện song song các bước sau:
DEV # 1: bắt đầu với một cú va chạm Django 1.11 (lý thuyết cho rằng Django 1.11 có thể được định vị tốt nhất như một điểm nhảy ra Django 2.x), sử dụng 2.7.
DEV # 2: bắt đầu với Python 3.6 / 3.7 của mã tiện ích không phải Django của bạn. Vì mã này tương thích 2.7 tại thời điểm này, hãy hợp nhất nó thành # 1 khi bạn đi.
Xem cách cả hai nhiệm vụ tiến hành, đánh giá rủi ro dự án liên quan đến Django là gì và nỗi đau của Python 3 trông như thế nào. Bạn đã thiếu Python 2.7 EOL, nhưng một khung web lỗi thời có lẽ nguy hiểm hơn so với Python 2.7 cũ, ít nhất là trong vài tháng. Vì vậy, tôi sẽ không chờ đợi quá lâu để bắt đầu di chuyển khỏi Django 1.9 và công việc của bạn sẽ không bị lãng phí. Khi bạn thấy tiến độ, bạn sẽ bắt đầu thấy rủi ro dự án tốt hơn.
Tiến trình 2to3 ban đầu của bạn sẽ chậm, nhưng công cụ và hướng dẫn đủ tốt để bạn nhanh chóng tăng tốc, vì vậy đừng lật đổ nó trước khi bắt đầu thu thập kinh nghiệm. Phía Django phụ thuộc vào mức độ tiếp xúc của bạn đối với các thay đổi trong khung, đó là lý do tại sao tôi nghĩ tốt nhất nên bắt đầu sớm.
PS (tranh cãi / ý kiến cá nhân) Tôi đã không sử dụng sáu hoặc nhiều thư viện cầu 2 đến 3 đóng hộp khác.
Không phải vì tôi không tin tưởng nó - thật tuyệt vời cho các lib của bên thứ 3 - mà là tôi không muốn thêm một phụ thuộc vĩnh viễn phức tạp (và tôi quá lười để đọc tài liệu của nó). Tôi đã viết 2.7 mã theo cú pháp tương thích 3.x trong một thời gian dài vì vậy tôi không thực sự cảm thấy cần phải sử dụng chúng. Số dặm của bạn có thể thay đổi và không được đặt ra trên con đường này nếu nó có vẻ như rất nhiều công việc .
Thay vào đó, tôi đã tạo một py223.py (57 LỘC bao gồm các bình luận) với loại nội dung này, hầu hết đều liên quan đến cách giải quyết cho sự phản đối và thay đổi tên trong thư viện chuẩn.
try:
basestring_ = basestring
except (NameError,) as e:
basestring_ = str
try:
cmp_ = cmp
except (NameError,) as e:
# from http://portingguide.readthedocs.io/en/latest/comparisons.html
def cmp_(x, y):
"""
Replacement for built-in function cmp that was removed in Python 3
"""
return (x > y) - (x < y)
Sau đó nhập từ py223 đó để giải quyết những mối quan tâm cụ thể đó. Sau này tôi sẽ bỏ việc nhập khẩu và chuyển những thứ kỳ lạ đó isinstance(x, basestr_)
sang isinstance(x, str)
nhưng tôi biết trước có chút lo lắng.