كيف يمكنني التحقق من الثعبان النسخة في برنامج يستخدم لغة جديدة الميزات ؟

StackOverflow https://stackoverflow.com/questions/446052

  •  22-07-2019
  •  | 
  •  

سؤال

إذا كان لدي بيثون السيناريو الذي يتطلب على الأقل معين نسخة من بيثون ، ما هو الطريق الصحيح إلى فشل بأمان عند إصدار سابق من الثعبان ويستخدم لإطلاق النص ؟

كيف يمكنني الحصول على السيطرة في وقت مبكر بما يكفي لإصدار رسالة خطأ و الخروج ؟

على سبيل المثال لدي برنامج يستخدم ternery المشغل (الجديد في 2.5) و "مع" كتل (الجديد في 2.6).كتبت قليلا بسيطة مترجم-نسخة مدقق الروتين الذي هو أول شيء البرنامج النصي اتصل ...إلا أنها لا تحصل على هذا الحد.بدلا من ذلك ، فشل البرنامج النصي أثناء الثعبان جمع قبل الروتينية حتى أنه دعا.وبالتالي فإن المستخدم من السيناريو يرى بعض جدا غامضة synax خطأ tracebacks - الذي تتطلب خبير أن نستنتج أنه هو ببساطة حالة تشغيل إصدار خاطئ من بيثون.

أنا أعرف كيفية التحقق من إصدار بيثون.المشكلة هي أن بعض بناء الجملة غير قانوني في الإصدارات القديمة من بيثون.النظر في هذا البرنامج:

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

عندما تعمل تحت 2.4 أريد هذه النتيجة

$ ~/bin/python2.4 tern.py 
must use python 2.5 or greater

وليس هذه النتيجة:

$ ~/bin/python2.4 tern.py 
  File "tern.py", line 5
    x = 1 if True else 2
           ^
SyntaxError: invalid syntax

(توجيه عن زميل في العمل.)

هل كانت مفيدة؟

المحلول

ويمكنك اختبار باستخدام eval:

try:
  eval("1 if True else 2")
except SyntaxError:
  # doesn't have ternary

وأيضا، with <م> هو متوفر في بيثون 2.5، فقط إضافة from __future__ import with_statement.

وتحرير: للحصول على تحكم في وقت مبكر بما فيه الكفاية، هل يمكن تقسيمه إلى ملفات .py مختلفة وتحقق التوافق في الملف الرئيسي قبل الاستيراد (على سبيل المثال في __init__.py في حزمة):

# __init__.py

# Check compatibility
try:
  eval("1 if True else 2")
except SyntaxError:
  raise ImportError("requires ternary support")

# import from another module
from impl import *

نصائح أخرى

هل لديك التفاف حول البرنامج أن يفعل ما يلي.

import sys

req_version = (2,5)
cur_version = sys.version_info

if cur_version >= req_version:
   import myApp
   myApp.run()
else:
   print "Your Python interpreter is too old. Please consider upgrading."

ويمكنك أن تنظر أيضا في استخدام sys.version()، إذا كنت تخطط لقاء الناس الذين يستخدمون ما قبل 2.0 المترجمين بيثون، ولكن بعد أن يكون لديك بعض التعابير العادية القيام به.

وربما تكون هناك طرق أكثر أناقة للقيام بذلك.

وحاول

import platform
platform.python_version()

ويجب أن تعطي لك سلسلة مثل "2.3.1". إذا لم يكن هذا بالضبط WAHT تريد أن هناك مجموعة غنية من البيانات المتاحة من خلال "منصة" البناء في. ماذا تريد أن تكون في مكان ما هناك.

ولعل أفضل طريقة للقيام بذلك مقارنة الإصدار هو استخدام sys.hexversion. هذا أمر مهم لأن المقارنة بين الصفوف النسخة لن تعطيك النتيجة المرجوة في كافة إصدارات الثعبان.

import sys
if sys.hexversion < 0x02060000:
    print "yep!"
else:
    print "oops!"
import sys    
# prints whether python is version 3 or not
python_version = sys.version_info.major
if python_version == 3:
    print("is python 3")
else:
    print("not python 3")

الجواب من Nykakin في AskUbuntu:

يمكنك أيضا التحقق من بيثون نسخة من القانون نفسه باستخدام platform وحدة من المكتبة القياسية.

هناك نوعان من الوظائف:

  • platform.python_version() (إرجاع سلسلة).
  • platform.python_version_tuple() (يعود tuple).

رمز بيثون

إنشاء ملف على سبيل المثال: version.py)

طريقة سهلة للتحقق من الإصدار:

import platform

print(platform.python_version())
print(platform.python_version_tuple())

يمكنك أيضا استخدام eval الطريقة:

try:
  eval("1 if True else 2")
except SyntaxError:
  raise ImportError("requires ternary support")

تشغيل الثعبان ملف في سطر الأوامر:

$ python version.py 
2.7.11
('2', '7', '11')

إخراج الثعبان مع CGI عبر WAMP Server على ويندوز 10:

Screenshot 2016-11-16 14.39.01 by Suriyaa Kudo


موارد مفيدة

أصبحت

ومجموعات جزءا من اللغة الأساسية في بيثون 2.4، من أجل البقاء متوافقة إلى الوراء. أنا فعلت هذا في ذلك الوقت، والتي سوف تعمل من أجلك أيضا:

if sys.version_info < (2, 4):
    from sets import Set as set

على الرغم من أن السؤال هو:كيف يمكنني الحصول على السيطرة في وقت مبكر بما يكفي لإصدار رسالة خطأ والخروج?

السؤال الذي لا إجابة هو:كيف يمكنني الحصول على السيطرة في وقت مبكر بما يكفي لإصدار رسالة خطأ قبل البدء في التطبيق?

أستطيع الإجابة عليه الكثير ثم بشكل مختلف الوظائف الأخرى.يبدو إجابات حتى الآن تحاول حل المسألة من خلال بايثون.

هل التحقق من الإصدار قبل إطلاق بيثون.أرى أن المسار الخاص بك هو لينكس أو يونيكس.ومع ذلك لا يسعني إلا أن أقدم لكم ويندوز النصي.أنا صورة تكييفه مع لينكس البرمجة الجملة لن يكون من الصعب جدا.

هنا هو دوس النصي مع الإصدار 2.7:

@ECHO OFF
REM see http://ss64.com/nt/for_f.html
FOR /F "tokens=1,2" %%G IN ('"python.exe -V 2>&1"') DO ECHO %%H | find "2.7" > Nul
IF NOT ErrorLevel 1 GOTO Python27
ECHO must use python2.7 or greater
GOTO EOF
:Python27
python.exe tern.py
GOTO EOF
:EOF

هذا لا يتم تشغيل أي جزء من التطبيق الخاص بك وبالتالي لن يرفع الثعبان استثناء.ولكنها لا تخلق أي ملف temp أو إضافة أي نظام تشغيل متغيرات البيئة.وهو لا ينتهي التطبيق الخاص بك إلى استثناء بسبب اختلاف الإصدار قواعد النحو.أن الثلاثة أقل ممكن من النقاط الأمنية من الوصول.

على FOR /F الخط هو المفتاح.

FOR /F "tokens=1,2" %%G IN ('"python.exe -V 2>&1"') DO ECHO %%H | find "2.7" > Nul

متعددة الثعبان النسخة التحقق من التحقق من عنوان url:http://www.fpschultze.de/modules/smartfaq/faq.php?faqid=17

و هاك نسخة:

[MS النصي.بيثون التحقق من الإصدار prelaunch من بيثون وحدة] http://pastebin.com/aAuJ91FQ

import sys
sys.version

سوف يكون الحصول على إجابة مثل هذا

'2.7.6 (الافتراضي ، Oct 26 2016, 20:30:19) \ن[دول مجلس التعاون الخليجي 4.8.4]'

هنا 2.7.6 هو الإصدار

وكما ذكر أعلاه، تحدث أخطاء في بناء الجملة في وقت الترجمة، وليس في وقت التشغيل. في حين بيثون هو "تفسير اللغة"، رمز بيثون ليست في الواقع تفسيرها مباشرة. انها ترجمة التعليمات البرمجية بايت، وهو ما يتم تفسيرها. هناك خطوة الترجمة يحدث عندما يتم استيراد وحدة نمطية (إذا لم يكن هناك نسخة جمعت بالفعل وذلك في شكل .pyc أو ملف .pyd) وذلك عندما كنت على خطأ، وليس (تماما تماما) عندما يتم تشغيل التعليمات البرمجية.

ويمكنك تأجيل الخطوة ترجمة وتحقيق ذلك في وقت التشغيل للحصول على خط واحد للقانون، إذا كنت تريد، وذلك باستخدام وحدة التقييم، كما ذكر أعلاه، ولكن أنا شخصيا يفضل تجنب القيام بذلك، لأنه يسبب بيثون لأداء يحتمل أن تكون غير ضرورية تجميع وقت التشغيل، لشيء واحد، وآخر، وأنه يخلق ما لي وكأننا فوضى التعليمات البرمجية. (إذا كنت تريد، يمكنك إنشاء التعليمات البرمجية التي يولد الرمز الذي يولد شفرة - ويكون لها وقت رائع للغاية تعديل وتصحيح الأخطاء التي في 6 أشهر من الآن.) لذلك ما أوصي بدلا من ذلك هو شيء أكثر من هذا القبيل:

import sys
if sys.hexversion < 0x02060000:
    from my_module_2_5 import thisFunc, thatFunc, theOtherFunc
else:
    from my_module import thisFunc, thatFunc, theOtherFunc

و.. الذي أود أن تفعل حتى لو لم يكن لدي سوى وظيفة واحدة أن تستخدم في بناء الجملة أحدث وكان قصير جدا. (في الواقع أود أن تتخذ كل التدابير المعقولة لتقليل عدد وحجم هذه الوظائف. حتى أنني قد كتابة دالة مثل ifTrueAElseB (كوند، أ، ب) مع أن سطر واحد من بناء الجملة في ذلك.)

وشيء آخر قد تكون تجدر الإشارة إليه (أي أنا قليلا عن دهشتها أحدا لم أشار بعد) هو أنه في حين لم الإصدارات السابقة من بيثون لا يدعم كود مثل

value = 'yes' if MyVarIsTrue else 'no'

و.. فعلت رمز دعم مثل

value = MyVarIsTrue and 'yes' or 'no'

وكانت تلك الطريقة القديمة في كتابة عبارات الثلاثي. ليس لدي بيثون 3 تثبيت بعد، ولكن بقدر ما أعرف، وبهذه الطريقة "القديمة" لا يزال يعمل حتى يومنا هذا، لذلك يمكنك أن تقرر لنفسك ما إذا كان يستحق ذلك لاستخدام بشروط بناء الجملة جديد، إذا كنت بحاجة لدعم استخدام الإصدارات القديمة من بيثون.

ضع ما يلي في أعلى جدا من الملف الخاص بك:

import sys

if float(sys.version.split()[0][:3]) < 2.7:
    print "Python 2.7 or higher required to run this code, " + sys.version.split()[0] + " detected, exiting."
    exit(1)

وبعد ذلك تواصل مع رمز بيثون العادي:

import ...
import ...
other code...

وأعتقد أن أفضل وسيلة لاختبار وظيفة بدلا من الإصدارات. في بعض الحالات، وهذا هو تافهة، وليس ذلك في بلدان أخرى.

وعلى سبيل المثال:

try :
    # Do stuff
except : # Features weren't found.
    # Do stuff for older versions.

وطالما كنت محددا في ما يكفي في استخدام حاول / باستثناء الكتل، يمكنك تغطية معظم القواعد الخاصة بك.

وأنا فقط وجدت هذا السؤال بعد بحث سريع في حين تحاول حل المشكلة نفسي وجئت مع هجين بناء على عدد قليل من الاقتراحات المذكورة أعلاه.

وأنا أحب فكرة DevPlayer للباستخدام برنامج نصي المجمع، ولكن الجانب السلبي هو أن ينتهي بك الأمر الحفاظ على مغلفة متعددة لأنظمة تشغيل مختلفة، لذلك قررت أن أكتب المجمع في بيثون، ولكن استخدام نفس الأساسية "والاستيلاء على نسخة عن طريق تشغيل اكس "المنطق وجاء مع هذا.

وأعتقد أنه يجب أن تعمل لمدة 2.5 وما بعده. لقد اختبرت على 2.66، 2.7.0 و 3.1.2 على لينكس و2.6.1 على OS X حتى الآن.

import sys, subprocess
args = [sys.executable,"--version"]

output, error = subprocess.Popen(args ,stdout = subprocess.PIPE, stderr = subprocess.PIPE).communicate()
print("The version is: '%s'"  %error.decode(sys.stdout.encoding).strip("qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLMNBVCXZ,.+ \n") )

ونعم، وأنا أعلم أن خط فك / قطاع النهائي أمر فظيع، ولكن أردت فقط لانتزاع بسرعة رقم الإصدار. انا ذاهب الى صقل ذلك.

وهذا يعمل بشكل جيد بما فيه الكفاية بالنسبة لي الآن، ولكن إذا كان أي شخص يمكن تحسينه (أو يقول لي لماذا انها فكرة رهيبة) التي تريد ان تكون باردة جدا.

ل<م> بذاتها مخطوطات الثعبان، ما يلي خدعة حدة docstring لفرض صيغة الثعبان (هنا v2.7.x) يعمل (اختبار على * لا شىء).

#!/bin/sh
''''python -V 2>&1 | grep -q 2.7 && exec python -u -- "$0" ${1+"$@"}; echo "python 2.7.x missing"; exit 1 # '''

import sys
[...]

وهذا يجب التعامل مع المفقودين الثعبان قابل للتنفيذ كذلك، ولكن لديه الاعتماد على البقرى. انظر> وأ href = "https://stackoverflow.com/questions/17458528/why-does-this-snippet-with-a-shebang-bin-sh-and-exec-python-inside-4-single-q" > هنا عن الخلفية.

ويمكنك التحقق مع sys.hexversion أو sys.version_info.

وsys.hexversion ليس إنسان ودية للغاية لأنه عدد عشري. sys.version_info هو الصفوف (tuple)، لذلك فمن أكثر ملاءمة للإنسان.

والتحقق من وجود بيثون 3.6 أو أحدث مع sys.hexversion:

import sys, time
if sys.hexversion < 0x30600F0:
    print("You need Python 3.6 or greater.")
    for _ in range(1, 5): time.sleep(1)
    exit()

والتحقق من وجود بيثون 3.6 أو أحدث مع sys.version_info:

import sys, time
if sys.version_info[0] < 3 and sys.version_info[1] < 6:
    print("You need Python 3.6 or greater.")
    for _ in range(1, 5): time.sleep(1)
    exit()

وsys.version_info هو أكثر إنسان ودية، ولكنه يأخذ المزيد من الشخصيات. وأود أن أوصى sys.hexversion، على الرغم من أنها أقل ودية البشرية.

وآمل أن يكون هذا ساعد لك!

وأنا التوسع في الإجابة ممتازة akhan الذي يطبع رسالة مفيدة <م> قبل السيناريو بيثون وحتى المترجمة.

إذا كنت ترغب في التأكد من أن السيناريو يتم تشغيل مع بيثون 3.6 أو أحدث، إضافة هذين الخطين إلى أعلى بيثون السيناريو الخاص بك:

#!/bin/sh
''''python3 -c 'import sys; sys.exit(sys.version_info < (3, 6))' && exec python3 -u -- "$0" ${1+"$@"}; echo 'This script requires Python 3.6 or newer.'; exit 1 # '''

و(ملاحظة: يبدأ السطر الثاني مع أربعة ، علامات الاقتباس المفردة وينتهي <م> ثلاثة ، علامات الاقتباس المفردة هذه قد تبدو غريبة، ولكن ذلك ليس خطأ مطبعي.)

وميزة هذا الحل هو أن هذا الرمز مثل print(f'Hello, {name}!') لا يسبب SyntaxError إذا تم استخدام بيثون نسخة قديمة من 3.6. سترى هذه الرسالة مفيدة بدلا من ذلك:

This script requires Python 3.6 or newer.

وبطبيعة الحال، هذا الحل يعمل فقط على قذائف يونكس الشبيهة، وفقط عندما يتم استدعاء البرنامج النصي مباشرة (مثل: ./script.py)، ومع السليم تنفيذ مجموعة بت إذن

وماذا عن هذا:

import sys

def testPyVer(reqver):
  if float(sys.version[:3]) >= reqver:
    return 1
  else:
    return 0

#blah blah blah, more code

if testPyVer(3.0) == 1:
  #do stuff
else:
  #print python requirement, exit statement

المشكلة هو بسيط جدا.يمكنك التحقق إذا كان الإصدار أقل من 2.4 ليس أقل من أو يساوي.حتى إذا Python version 2.4, ليس أقل من 2.4.ما يجب أن يكون قد تم:

    if sys.version_info **<=** (2, 4):

, لا

    if sys.version_info < (2, 4):
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top