2009-12-09 18 views
8

Chủ đề này đã làm phiền tôi một thời gian.Hỗ trợ các phiên bản khác nhau của Python

Đối với my Python project Tôi muốn có thể hỗ trợ các phiên bản Python từ 2.4 đến 3.1. Tôi nghĩ một chút về cách làm điều này, và cuối cùng quyết định có bốn nhánh riêng biệt của mã nguồn cho bốn phiên bản Python khác nhau: 2,4, 2,5, 2,6 và 3,1.

Tôi đã đến để xem đó là một quyết định tồi, chủ yếu là do phiền toái phân phối của Python, mà bây giờ tôi phải làm bốn lần thay vì một.

Câu hỏi đặt ra là phải làm gì?

Dự án của tôi nằm trong lĩnh vực điện toán khoa học. Tôi có ấn tượng rằng vẫn còn nhiều người phụ thuộc vào Python 2.4.

Có người đề xuất tôi chỉ viết toàn bộ dự án của mình cho 2,4, nhưng điều đó là không thể chấp nhận đối với tôi. Điều đó có nghĩa là tôi không thể sử dụng các nhà quản lý ngữ cảnh, và đó là điều tôi sẽ không từ bỏ.

Dự án Python thông thường hỗ trợ 2,4 như thế nào? Họ có tránh sử dụng các trình quản lý ngữ cảnh không?

Ngoài ra, có lựa chọn nào khác ngoài việc có một ngã ba riêng biệt cho Python 3.1 không? Tôi biết có tất cả các loại hacks để làm cho cùng một mã chạy trên 2.x và 3.x, nhưng một trong những lý do tôi thích Python là vì mã là đẹp, và tôi sẽ không tha thứ làm cho nó xấu xí với hacks tương thích.

Xin vui lòng cho tôi ý kiến ​​của bạn.

Trả lời

1

Có, bạn cần phải viết cho Python 2.4 cú pháp để hỗ trợ tất cả 2,4 - 2,7 trong cùng một codebase.

Một số thay đổi trong Python 2.6 và 2.7 nhằm giúp bạn viết mã tương thích dễ dàng hơn một chút với 3.x, nhưng bạn phải thả hỗ trợ từ 2.5 trở xuống để thực hiện điều đó.

+0

Tôi hiểu. Tôi sẵn sàng khám phá các tùy chọn KHÔNG làm điều đó trong cùng một codebase. Trong thực tế đó là những gì tôi đang làm bây giờ, trong cùng cực, có dĩa riêng biệt cho các phiên bản khác nhau. Có lẽ tôi có thể làm điều đó thông minh hơn. –

0

Nếu sự khác biệt giữa các phiên bản không khắc nghiệt, bạn có thể thử cách ly chúng thành một gói hoặc mô-đun riêng biệt, trong đó bạn viết mã phiên bản cụ thể để hoạt động như một lớp thích ứng.

Trong thời trang nhỏ, điều này có thể được thực hiện mà không có mô-đun riêng trong các trường hợp đơn giản, chẳng hạn như khi phiên bản mới của Python làm cho gói tiêu chuẩn được sử dụng bên ngoài, chẳng hạn như (ví dụ) simplejson. Chúng tôi có một cái gì đó tương tự như sau trong một số mã:

try: 
    import simplejson as json 
except ImportError: 
    import json 

Đối với công cụ không tầm thường, chẳng hạn như những gì bạn có thể có, bạn sẽ không muốn những điều đó nằm rải rác ngẫu nhiên trên khắp cơ sở mã của bạn, vì vậy bạn nên thu thập tất cả cùng nhau ở một nơi, khi có thể và làm cho phần duy nhất của mã của bạn là phiên bản cụ thể.

Điều này không thể hoạt động tốt cho những thứ mà cú pháp khác, chẳng hạn như nhận xét của bạn về việc muốn sử dụng trình quản lý ngữ cảnh. Chắc chắn, bạn có thể đặt mã trình quản lý ngữ cảnh trong một mô-đun riêng biệt, nhưng điều đó có thể sẽ làm phức tạp những nơi bạn sẽ sử dụng nó. Trong những trường hợp như vậy, bạn có thể backport một số tính năng quan trọng nhất định (tôi nghĩ rằng các trình quản lý ngữ cảnh có thể được mô phỏng một cách dễ dàng) với mô-đun bộ điều hợp này.

Chắc chắn có mã số riêng biệt là về điều tồi tệ nhất bạn có thể làm, vì vậy tôi chắc chắn khuyên bạn nên làm việc tránh xa điều đó.Ít nhất, không tự ý sử dụng các tính năng từ các phiên bản Python mới hơn, vì mặc dù nó có vẻ đẹp khi có chúng trong mã (đơn giản hóa một khối logic cụ thể), thực tế là bạn phải sao chép logic đó bằng cách giả mạo codebase, ngay cả trên một mô-đun duy nhất, sẽ nhiều hơn phủ nhận lợi ích.

Chúng tôi gắn bó với các phiên bản cũ hơn cho mã cũ, tinh chỉnh khi các bản phát hành mới xuất hiện để hỗ trợ chúng nhưng vẫn duy trì hỗ trợ cho các phiên bản cũ hơn, đôi khi có các lớp bộ điều hợp nhỏ. Tại một thời điểm nào đó, một bản phát hành chính của mã của chúng tôi sẽ hiển thị theo lịch biểu và chúng tôi xem xét liệu đã đến lúc phải bỏ hỗ trợ cho một Python cũ hơn. Khi điều đó xảy ra, chúng tôi cố gắng nhảy nhiều phiên bản, đi (ví dụ) từ 2,4 đến 2,6 trực tiếp, và chỉ sau đó mới bắt đầu thực sự tận dụng cú pháp mới và các tính năng không thể thích ứng.

0

Trước hết cuộc gọi, bạn cần lưu ý rằng cổ phiếu Python 2.x chủ yếu là cùng cú pháp tương thích ngược, các tính năng mới & bổ sung sang một bên. Có những thứ khác để xem xét rằng không nhất thiết phải là lỗi, chẳng hạn như Khước từ Thông báoCảnh báo rằng trong khi không gây bất lợi, xấu xí và có thể gây nhầm lẫn.

Python 3.x không tương thích ngược theo thiết kế và dự định để lại tất cả các hành trình cũ phía sau. Python 2.6 đã giới thiệu nhiều thay đổi cũng có trong Python 3.x để giúp dễ dàng chuyển đổi. Để xem tất cả chúng tôi khuyên bạn nên đọc trên tài liệu What's New in Python 2.6. Vì lý do này, rất có thể viết mã cho Python 2.6 cũng sẽ chạy trong Python 3.1, nhưng đó không phải là không có sự cẩn trọng của nó.

Thậm chí vẫn còn có nhiều thay đổi cú pháp nhỏ ngay cả giữa các phiên bản 2.x sẽ yêu cầu bạn quấn nhiều mã trong các khối try/except, vì vậy nếu đây là những gì bạn sẵn sàng làm sau đó có 2 .x và 3.x nhánh là hoàn toàn có thể. Tôi nghĩ bạn sẽ thấy rằng bạn sẽ làm rất nhiều thuộc tính và kiểm tra kiểu trên các đối tượng của bạn để làm những gì bạn muốn làm.

Tôi khuyên bạn nên kiểm tra mã của các dự án lớn trên mạng có hỗ trợ nhiều phiên bản Python khác nhau. Twisted Matrix là cái đầu tiên xuất hiện trong đầu bạn. Mã của họ là một ví dụ tuyệt vời về cách viết mã Python.

Cuối cùng, những gì bạn đang đặt ra để làm sẽ không dễ dàng, vì vậy hãy chuẩn bị cho mình rất nhiều công việc!

+0

Bạn thấy các nhánh khác nhau ở đâu trong 2,4-2,6? Tôi thấy các bản tải xuống nhị phân khác nhau cho Windows, nhưng nguồn có vẻ giống như một thư mục. Tôi đã bỏ lỡ bất cứ điều gì? –

+0

'set' và' frozenset' được thêm vào trong ** Python 2.4 **. http://www.python.org/doc/2.4.4/whatsnew/whatsnew24.html – u0b34a0f6ae

+0

@ cool-RR - Không, tôi đã bỏ lỡ điều gì đó. Tôi đã xóa thông tin xấu. @ kaizer.se - Cảm ơn, tôi đã nhầm lẫn với việc sử dụng mô-đun 'sets' với việc bổ sung các kiểu được tích hợp sẵn. – jathanism

1

Có vẻ như có những câu trả lời khác nhau cho vấn đề của bạn.

Thứ nhất, nếu bạn muốn cung cấp tất cả chức năng cho tất cả phiên bản python thì có, có lẽ bạn đang bị mắc kẹt với việc sử dụng các tập hợp con chức năng nhỏ nhất có thể - do đó viết mã của bạn cho Python 2.4. Hoặc bạn có thể backport các tính năng từ các trình thông dịch mới hơn nếu chúng là python tinh khiết (đó không phải là trường hợp của các trình quản lý ngữ cảnh hoặc các coroutines). Hoặc bạn có thể chia nhỏ hỗ trợ phiên bản thành các tính năng - nếu bạn nghĩ rằng có một tính năng (tùy chọn) có lợi ích lớn từ người quản lý ngữ cảnh, bạn có thể làm cho nó có sẵn trong một mô-đun riêng và chỉ nói rằng 2,4 người dùng không có tính năng đó.

Để hỗ trợ Python 3 hãy xem trợ giúp 2to3, nếu bạn viết mã đúng cách, bạn sẽ không cần phải duy trì hai mã riêng biệt.

0

Bạn có thể thử virtualenv và phân phối ứng dụng của mình bằng phiên bản Python đơn. Điều này có thể hoặc có thể không thực tế trong trường hợp của bạn mặc dù.

0

Chúng tôi có vấn đề liên quan, một hệ thống lớn hỗ trợ cả jython và cpython trở lại 2.4.Về cơ bản, bạn cần phải tách biệt mã cần phải được viết khác nhau thành một nhóm nhỏ các mô-đun hy vọng và có những thứ được nhập khẩu có điều kiện.

# module svn.py 
import sys 
if sys.platform.startswith('java'): 
    from jythonsvn import * 
else: 
    from nativesvn import * 

Trong ví dụ của bạn, bạn sẽ sử dụng các thử nghiệm đối với sys.version_info, có lẽ là. Bạn có thể xác định một số điều đơn giản trong một module tiện ích, mà bạn sẽ sử dụng như: từ util nhập khẩu *

# module util.py 
import sys 
if sys.exc_info[0] == 2: 
    if sys.exc_info[1] == 4: 
     from util_py4 import * 
    ... 

Sau đó, mọi thứ trong util_py4.py như:

def any(seq):    # define workaround functions where possible 
    for a in seq: 
     if a: return True 
    return False 
... 

Mặc dù đây là một vấn đề khác với porting (kể từ khi bạn muốn tiếp tục hỗ trợ), liên kết này cung cấp một số hướng dẫn hữu ích http://python3porting.com/preparing.html (cũng như một loạt các bài viết khác về việc chuyển python 2.x).

Nhận xét của bạn rằng bạn không thể sống mà không có người quản lý ngữ cảnh có chút khó hiểu. Trong khi các trình quản lý ngữ cảnh mạnh mẽ và làm cho mã dễ đọc hơn và giảm thiểu nguy cơ lỗi, bạn sẽ không thể có chúng trong mã phiên bản 2.4 của mình.

### 2.5 (with appropriate future import) and later 
with open('foo','rb')as myfile: 
    # do something with myfile 

### 2.4 and earlier 
myfile = None 
try: 
    myfile = open('foo','rb') 
    # do something with myfile 
finally: 
    if myfile: myfile.close() 

Vì bạn muốn hỗ trợ 2.4, bạn sẽ có một phần mã chỉ cần có cú pháp thứ hai. Nó sẽ thực sự thanh lịch hơn để viết nó ra sao?