Jika saya memiliki skrip Python yang membutuhkan setidaknya versi Python tertentu, apa cara yang benar untuk gagal dengan anggun ketika versi Python sebelumnya digunakan untuk meluncurkan skrip?
Bagaimana cara mendapatkan kontrol cukup awal untuk mengeluarkan pesan kesalahan dan keluar?
Sebagai contoh, saya memiliki program yang menggunakan operator ternery (baru dalam 2,5) dan "dengan" blok (baru dalam 2,6). Saya menulis rutin kecil pemeriksa versi interpreter yang merupakan hal pertama yang akan dipanggil skrip ... kecuali itu tidak sampai sejauh itu. Sebagai gantinya, skrip gagal selama kompilasi python, bahkan sebelum rutinitas saya dipanggil. Dengan demikian pengguna skrip melihat beberapa tracebacks kesalahan synax sangat jelas - yang cukup banyak membutuhkan ahli untuk menyimpulkan bahwa itu hanya kasus menjalankan versi yang salah dari Python.
Saya tahu cara memeriksa versi Python. Masalahnya adalah bahwa beberapa sintaks ilegal di versi Python yang lebih lama. Pertimbangkan program ini:
import sys
if sys.version_info < (2, 4):
raise "must use python 2.5 or greater"
else:
# syntax error in 2.4, ok in 2.5
x = 1 if True else 2
print x
Ketika dijalankan di bawah 2.4, saya ingin hasil ini
$ ~/bin/python2.4 tern.py
must use python 2.5 or greater
dan bukan hasil ini:
$ ~/bin/python2.4 tern.py
File "tern.py", line 5
x = 1 if True else 2
^
SyntaxError: invalid syntax
(Menyalurkan untuk rekan kerja.)
Jawaban:
Anda dapat menguji menggunakan
eval
:Juga,
with
adalah tersedia dalam Python 2.5, hanya menambahkanfrom __future__ import with_statement
.EDIT: untuk mendapatkan kontrol cukup awal, Anda dapat membaginya menjadi
.py
file yang berbeda dan memeriksa kompatibilitas di file utama sebelum mengimpor (misalnya dalam__init__.py
dalam paket):sumber
exec
alih-aliheval
. Saya punya ini muncul ketika mencoba untuk menulis fungsi yang akan mencetak ke stderr di kedua py2k dan py3k.import
stasiun di coba / kecuali). Perhatikan bahwa Anda mungkin perlu memeriksa hal-hal lain selainSyntaxError
juga (mis. Fungsi builtin atau penambahan ke perpustakaan standar)Miliki pembungkus di sekitar program Anda yang melakukan hal berikut.
Anda juga dapat mempertimbangkan untuk menggunakan
sys.version()
, jika Anda berencana untuk bertemu orang-orang yang menggunakan interpreter Python pra-2.0, tetapi kemudian Anda memiliki beberapa ekspresi reguler untuk dilakukan.Dan mungkin ada cara yang lebih elegan untuk melakukan ini.
sumber
sys.version_info
bukan fungsi.import this
. Pengalihan yang indah.Mencoba
Seharusnya memberi Anda string seperti "2.3.1". Jika ini tidak persis seperti yang Anda inginkan, ada serangkaian data yang tersedia melalui build-in "platform". Apa yang Anda inginkan harus ada di suatu tempat.
sumber
print(platform.python_version())
bukannyaplatform.python_version()
!Mungkin cara terbaik untuk melakukan perbandingan versi ini adalah dengan menggunakan
sys.hexversion
. Ini penting karena membandingkan versi tupel tidak akan memberi Anda hasil yang diinginkan di semua versi python.sumber
sumber
sys.version_info
adalah tidak tupel bernama. Anda harus menggunakansys.version_info[0]
nomor versi utama, dansys.version_info[1]
untuk minor.Anda juga dapat memeriksa versi Python dari kode itu sendiri menggunakan
platform
modul dari pustaka standar.Ada dua fungsi:
platform.python_version()
(mengembalikan string).platform.python_version_tuple()
(mengembalikan tuple).Kode Python
Metode mudah untuk memeriksa versi:
Anda juga dapat menggunakan
eval
metode ini:Jalankan file Python di baris perintah:
Output Python dengan CGI melalui Server WAMP pada Windows 10:
Sumber daya yang bermanfaat
sumber
Set menjadi bagian dari bahasa inti dalam Python 2.4, agar tetap kompatibel. Saya melakukan ini saat itu, yang akan bekerja untuk Anda juga:
sumber
try: set except NameError: from sets import Set as set
Meskipun pertanyaannya adalah: Bagaimana cara mendapatkan kontrol cukup awal untuk mengeluarkan pesan kesalahan dan keluar ?
Pertanyaan yang saya jawab adalah: Bagaimana saya mendapatkan kontrol cukup awal untuk mengeluarkan pesan kesalahan sebelum memulai aplikasi ?
Saya bisa menjawabnya dengan sangat berbeda dari posting lainnya. Tampaknya jawaban sejauh ini mencoba menyelesaikan pertanyaan Anda dari dalam Python.
Saya katakan, lakukan pengecekan versi sebelum meluncurkan Python. Saya melihat jalur Anda adalah Linux atau unix. Namun saya hanya bisa menawarkan Anda skrip Windows. Saya gambar mengadaptasikannya ke sintaks scripting linux tidak akan terlalu sulit.
Berikut ini skrip DOS dengan versi 2.7:
Ini tidak menjalankan bagian mana pun dari aplikasi Anda dan karenanya tidak akan meningkatkan Pengecualian Python. Itu tidak membuat file temp atau menambahkan variabel lingkungan OS. Dan itu tidak mengakhiri aplikasi Anda ke pengecualian karena aturan sintaksis versi yang berbeda. Itu tiga titik keamanan akses yang kurang memungkinkan.
The
FOR /F
line adalah kuncinya.Untuk beberapa versi python, periksa url: http://www.fpschultze.de/modules/smartfaq/faq.php?faqid=17
Dan versi retas saya:
[Skrip MS; Versi Python memeriksa prelaunch modul Python] http://pastebin.com/aAuJ91FQ
sumber
akan mendapat jawaban seperti ini
di sini 2.7.6 adalah versi
sumber
Seperti disebutkan di atas, kesalahan sintaksis terjadi pada waktu kompilasi, bukan pada saat dijalankan. Sementara Python adalah "bahasa yang ditafsirkan", kode Python sebenarnya tidak langsung ditafsirkan; itu dikompilasi ke kode byte, yang kemudian ditafsirkan. Ada langkah kompilasi yang terjadi ketika modul diimpor (jika tidak ada versi yang sudah dikompilasi tersedia dalam bentuk file .pyc atau .pyd) dan saat itulah Anda mendapatkan kesalahan Anda, tidak (tepatnya) ketika kode Anda sedang berjalan.
Anda dapat menunda langkah kompilasi dan mewujudkannya pada saat dijalankan untuk satu baris kode, jika Anda ingin, dengan menggunakan eval, seperti yang disebutkan di atas, tetapi saya pribadi lebih suka menghindari melakukan itu, karena hal itu menyebabkan Python melakukan berpotensi kompilasi run-time yang tidak perlu, untuk satu hal, dan untuk yang lain, itu menciptakan apa yang bagi saya terasa seperti kekacauan kode. (Jika Anda mau, Anda dapat membuat kode yang menghasilkan kode yang menghasilkan kode - dan memiliki waktu yang sangat luar biasa memodifikasi dan men-debug itu dalam 6 bulan dari sekarang.) Jadi yang saya sarankan adalah sesuatu yang lebih seperti ini:
.. yang akan saya lakukan bahkan jika saya hanya memiliki satu fungsi yang menggunakan sintaks yang lebih baru dan itu sangat singkat. (Sebenarnya saya akan mengambil setiap tindakan yang masuk akal untuk meminimalkan jumlah dan ukuran fungsi tersebut. Saya bahkan mungkin menulis fungsi seperti ifTrueAElseB (cond, a, b) dengan satu baris sintaks di dalamnya.)
Hal lain yang mungkin perlu ditunjukkan (bahwa saya sedikit kagum belum ada yang menunjukkan) adalah bahwa sementara versi Python sebelumnya tidak mendukung kode seperti
..itu memang mendukung kode suka
Itu adalah cara lama menulis ekspresi ternary. Saya belum menginstal Python 3, tetapi sejauh yang saya tahu, cara "lama" itu masih berfungsi hingga hari ini, jadi Anda dapat memutuskan sendiri apakah layak menggunakan kondisional baru dengan syarat, jika Anda perlu untuk mendukung penggunaan versi Python yang lebih lama.
sumber
a and b or c
alih - alihb if a else c
, itu tidak setara; jikab
palsu itu akan gagal, menghasilkana
bukanb
.Letakkan yang berikut di bagian paling atas file Anda:
Kemudian lanjutkan dengan kode Python normal:
sumber
sys.version_info < (2, 7)
sys.version_info
jenis ini dengan tuple berfungsi?sys.version_info
dulu tuple; misalnya(2, 4, 6, 'final', 0)
; hanya dalam Python 3 dan 2,7 itu diubah menjadi tipe yang terpisah, yang bagaimanapun sebanding dengan tupel.Saya pikir cara terbaik adalah menguji fungsionalitas daripada versi. Dalam beberapa kasus, ini sepele, tidak demikian dalam kasus lain.
misalnya:
Selama Anda cukup spesifik dalam menggunakan blok coba / kecuali, Anda dapat mencakup sebagian besar pangkalan Anda.
sumber
Saya baru saja menemukan pertanyaan ini setelah pencarian cepat sambil mencoba menyelesaikan masalah sendiri dan saya telah menghasilkan hibrida berdasarkan beberapa saran di atas.
Saya suka ide DevPlayer menggunakan skrip pembungkus, tetapi downside adalah bahwa Anda akhirnya mempertahankan beberapa pembungkus untuk OS yang berbeda, jadi saya memutuskan untuk menulis pembungkus dengan python, tetapi menggunakan dasar yang sama "ambil versi dengan menjalankan exe" logika dan datang dengan ini.
Saya pikir itu harus bekerja untuk 2,5 dan seterusnya. Saya sudah mengujinya pada 2.66, 2.7.0 dan 3.1.2 di Linux dan 2.6.1 pada OS X sejauh ini.
Ya, saya tahu decode / strip akhir mengerikan, tetapi saya hanya ingin cepat mengambil nomor versi. Aku akan memperbaikinya.
Ini bekerja cukup baik untuk saya untuk saat ini, tetapi jika ada yang bisa memperbaikinya (atau memberi tahu saya mengapa itu ide yang buruk) itu akan keren juga.
sumber
Untuk skrip python mandiri , trik mendokumentasikan modul berikut untuk menegakkan versi python (di sini v2.7.x) berfungsi (diuji pada * nix).
Ini harus menangani executable python yang hilang juga tetapi memiliki ketergantungan pada grep. Lihat di sini untuk latar belakang.
sumber
Anda dapat memeriksa dengan
sys.hexversion
atausys.version_info
.sys.hexversion
tidak terlalu ramah manusia karena merupakan angka heksadesimal.sys.version_info
adalah tuple, jadi lebih ramah manusia.Periksa Python 3.6 atau yang lebih baru dengan
sys.hexversion
:Periksa Python 3.6 atau yang lebih baru dengan
sys.version_info
:sys.version_info
lebih ramah manusia, tetapi membutuhkan lebih banyak karakter. Saya akan merekomendasikansys.hexversion
, meskipun kurang ramah manusia.Saya harap ini membantu Anda!
sumber
Saya memperluas jawaban yang sangat baik dari akhan, yang mencetak pesan yang membantu sebelum skrip Python dikompilasi.
Jika Anda ingin memastikan bahwa skrip sedang dijalankan dengan Python 3.6 atau yang lebih baru, tambahkan dua baris ini di bagian atas skrip Python Anda:
(Catatan: Baris kedua dimulai dengan empat tanda kutip tunggal dan berakhir dengan tiga tanda kutip tunggal. Ini mungkin terlihat aneh, tetapi ini bukan kesalahan ketik.)
Keuntungan dari solusi ini adalah bahwa kode seperti
print(f'Hello, {name}!')
tidak akan menyebabkanSyntaxError
jika versi Python yang lebih lama dari 3,6 digunakan. Anda akan melihat pesan bermanfaat ini sebagai gantinya:Tentu saja, solusi ini hanya bekerja pada shell mirip Unix, dan hanya ketika skrip dipanggil secara langsung (seperti
./script.py
:), dan dengan bit izin eXecute yang tepat ditetapkan.sumber
Bagaimana dengan ini:
sumber
Masalahnya cukup sederhana. Anda memeriksa apakah versinya kurang dari 2.4, tidak kurang dari atau sama dengan . Jadi jika versi Python adalah 2.4, itu tidak kurang dari 2.4. Apa yang seharusnya Anda miliki adalah:
tidak
sumber