2010-08-27 22 views
21

Có cách nào tiêu chuẩn để đảm bảo tập lệnh python sẽ được diễn giải bởi python2 chứ không phải python3? Trên bản phân phối của tôi, tôi có thể sử dụng #!/Usr/bin/env python2 làm shebang, nhưng có vẻ như không phải tất cả các bản phân phối đều là "python2". Tôi có thể gọi một phiên bản cụ thể (ví dụ 2.6) của python, nhưng điều đó sẽ loại trừ những người không có phiên bản đó.Có cách nào tiêu chuẩn để đảm bảo tập lệnh python sẽ được python2 giải thích và không phải python3?

Dường như với tôi rằng điều này sẽ ngày càng trở thành một vấn đề khi distro sẽ bắt đầu đặt python3 làm trình thông dịch python mặc định.

Trả lời

7

Đây là một chút vấn đề lộn xộn trong thời gian chuyển đổi rất dài. Thật không may, không có cách nào để chống lừa đảo, có nền tảng chéo để đảm bảo phiên bản Python nào đang được gọi, ngoài việc có bản thân kịch bản Python kiểm tra khi đã bắt đầu. Nhiều, nếu không phải hầu hết, các bản phân phối gửi Python 3 đều đảm bảo lệnh python chung được đặt bí danh theo mặc định cho phiên bản Python 2 gần đây nhất trong khi python3 được đặt bí danh cho Python gần đây nhất 3. Các bản phân phối không nên được khuyến khích thực hiện vì thế. Nhưng không có gì đảm bảo rằng người dùng sẽ không ghi đè điều đó.Tôi nghĩ rằng thực tiễn tốt nhất có sẵn trong tương lai gần là dành cho các nhà đóng gói, nhà phân phối và người dùng giả sử python đề cập đến Python 2 và khi cần thiết, hãy tạo kiểm tra thời gian chạy vào tập lệnh.

+0

Và, nếu cần thiết, như kwatford chỉ ra trong bình luận của mình, bao gồm một kiểm tra tại thời gian cài đặt trong kịch bản 'setup.py' của gói hoặc tương đương từ' setuptools', 'Distribute',' pip' et al. thường thay đổi các dòng shebang của kịch bản để trỏ đến cá thể cài đặt Python. –

+2

IMHO luôn luôn có sẵn symlink 'python2' để tạo ra trong tương lai, [shebangs có thể phân biệt rõ ràng] (http://unix.stackexchange.com/questions/26573/python-python2-or-python-python3-how- to-package-distribution-python-py2k) –

+1

@Grzegorz: Python PEP 394 mở về chủ đề đó và có khả năng sẽ được triển khai trong bản cập nhật trong tương lai cho Python 2: http://bugs.python.org/issue12627 –

11

http://docs.python.org/library/sys.html#sys.version_info

sử dụng các mô-đun sys bạn có thể xác định phiên bản python đang chạy và nâng cao một ngoại lệ hoặc thoát hoặc bất cứ điều gì bạn muốn.

CẬP NHẬT:

Bạn có thể sử dụng quyền này để gọi cho thông dịch viên thích hợp. Ví dụ: thiết lập một tập lệnh nhỏ thực hiện việc kiểm tra cho bạn và sử dụng tập lệnh đó trong shbang. Nó sẽ kiểm tra phiên bản python đang chạy, và nếu không phải là những gì bạn muốn, hãy tìm một phiên bản bạn muốn. Sau đó, nó sẽ chạy kịch bản trong phiên bản đó của python (hoặc thất bại nếu không có gì tốt được tìm thấy).

+1

Xem bình luận của tôi để jathanism. –

0

Vì tôi hiểu các bản phân phối khác nhau sẽ ở các vị trí khác nhau trong ổ của bạn. Dưới đây là một số đề xuất đến với tâm trí -

  1. Bạn có thể sử dụng bí danh UNIX để tạo lối tắt trỏ đến các bản phân phối khác nhau. Ví dụ: alias py2 = "/ usr/bin/python2.X". Vì vậy, khi bạn chạy tập lệnh, bạn có thể sử dụng py2 xx.py
  2. Hoặc cách khác có thể là sửa đổi biến môi trường PYTHON_PATH của bạn.
  3. Hoặc nếu tôi không sai có một điều khoản trong mô-đun sys để có được số phiên bản python hiện tại. Bạn có thể nhận được rằng thỏa thuận & một cách thích hợp.

này nên làm điều đó ...

+3

Tôi đang phân phối ứng dụng python, vấn đề của tôi là đảm bảo ** tất cả người dùng ** sử dụng python2.x để chạy ứng dụng của tôi. –

7

Sử dụng sys.version_info bạn có thể làm một bài kiểm tra giá trị đơn giản chống lại nó. Ví dụ, nếu bạn chỉ muốn hỗ trợ phiên bản 2.6 hoặc thấp hơn:

import sys 
if sys.version_info > (2,6): 
    sys.exit("Sorry, only we only support up to Python 2.6!") 
+1

Đó không phải là những gì tôi muốn, tôi muốn thông dịch viên được chọn tự động, không in thông báo lỗi nếu thông báo sai được chọn: -/ –

+0

Câu trả lời cuối cùng cho câu hỏi của bạn là: "Không, không có cách nào tiêu chuẩn để đảm bảo rằng một tập lệnh python sẽ được giải thích bởi python2 và không phải python3. " Những gì bạn yêu cầu là đảm bảo rằng Python2 đã được chọn trên 3. Bạn không chỉ định rằng bạn muốn trình thông dịch chính xác được chọn tự động. Cách duy nhất bạn có thể thực hiện điều này chắc chắn là thực hiện kiểm tra trước khi chương trình được gọi (chẳng hạn như với tập lệnh shell), sau đó chạy mã Python của bạn dựa vào trình thông dịch Python mong muốn. – jathanism

+2

Mong đợi "thông dịch viên tốt được chọn tự động" là vô lý. Một tệp không thể bắt buộc chương trình nào chạy nó. –

-1

Tôi tin rằng điều này sẽ làm những gì bạn muốn, cụ thể là thử nghiệm cho một phiên bản không đặc hiệu của Python ít hơn 3.x (miễn là nó doesn không chứa tuyên bố from __future__ import print_function).

try: 
    py3 = eval('print') 
except SyntaxError: 
    py3 = False 

if py3: exit('requires Python 2') 
... 

Nó hoạt động bằng cách kiểm tra để xem nếu print là một hàm built-in như trái ngược với một tuyên bố, vì nó là trong Python3. Khi nó không phải là một hàm, hàm eval() sẽ tăng một ngoại lệ, có nghĩa là mã đang chạy trên trình thông dịch pre-Python 3.0 với thông báo trước được đề cập ở trên.

2

Không hoàn toàn giống tình huống, nhưng công ty tôi làm việc cho có một ứng dụng có thể chạy các tập lệnh Python (trong số nhiều tính năng của nó). Sau nhiều vấn đề hỗ trợ liên quan đến việc cài đặt Python trên các nền tảng khác nhau, chúng tôi quyết định chỉ cài đặt trình thông dịch Python của riêng chúng ta với ứng dụng. Bằng cách đó, chúng tôi biết chính xác nơi nó được cài đặt và phiên bản đó là gì. Cách tiếp cận này có thể quá nặng đối với nhu cầu của bạn (gói Python chỉ khoảng 10% số bit của ứng dụng của chúng tôi) nhưng nó chắc chắn hoạt động.

+0

Đây thực sự là một cách tiếp cận tuyệt vời mà cắt ra tất cả các jiggering cần thiết cho một yêu cầu cứng nhắc như vậy. – jathanism

2

Phụ thuộc vào cách bạn phân phối nó, tôi đoán vậy.

Nếu bạn đang sử dụng một setup.py tập tin bình thường để quản lý phân phối của bạn, có nó bom ra nếu người dùng đang cố gắng để cài đặt nó bằng Python 3.

Sau khi cài đặt, các công việc của kịch bản điều khiển được tạo ra bởi (nói) setuptools có thể sẽ được liên kết với thông dịch cụ thể được sử dụng để cài đặt nó.

Nếu bạn đang làm điều gì đó kỳ lạ cho cài đặt của mình, bạn có thể sử dụng bất kỳ tập lệnh cài đặt nào mà bạn đang sử dụng tìm kiếm trình thông dịch python và lưu trữ lựa chọn. Trước tiên, bạn có thể kiểm tra xem bất kỳ điều gì được gọi là "python" là 2.x. Nếu không, hãy kiểm tra "python2.7", "python2.6", v.v. để xem những gì có sẵn.

0

Bạn có thể sử dụng các autotools để chọn trình thông dịch Python 2. Here là cách thực hiện điều đó. Đảm bảo một shebang chính xác có thể được khôn lanh để làm thanh lịch; here là một cách để thực hiện điều đó. Nó có thể dễ dàng hơn để chỉ cần có một kịch bản ánh sáng Bash wrapper, wrapper.sh.in trông giống như sau:

#!/bin/bash 
PYTHON2="@[email protected]" #That first link enables this autotool variable 
"$PYTHON2" "[email protected]" #Call the desired Python 2 script with its arguments 

Gọi wrapper.sh (sau một ./configure) như:

./wrapper.sh my_python2_script.py --an_option an_argument 
Các vấn đề liên quan