नई भाषा सुविधाओं का उपयोग करने वाले प्रोग्राम में मैं पायथन संस्करण की जांच कैसे कर सकता हूं?


239

यदि मेरे पास एक पायथन स्क्रिप्ट है, जिसे कम से कम पायथन के एक विशेष संस्करण की आवश्यकता है, तो स्क्रिप्ट को लॉन्च करने के लिए पायथन के पुराने संस्करण का उपयोग करने पर, इनायत से विफल होने का सही तरीका क्या है?

त्रुटि संदेश जारी करने और बाहर निकलने के लिए मुझे पर्याप्त नियंत्रण कैसे मिलेगा?

उदाहरण के लिए, मेरे पास एक प्रोग्राम है जो टर्निरी ऑपरेटर (2.5 में नया) और "ब्लॉक" (2.6 में नया) का उपयोग करता है। मैंने एक साधारण सा दुभाषिया-संस्करण चेकर रूटीन लिखा जो कि स्क्रिप्ट को कॉल करने वाली पहली चीज़ है ... सिवाय इसके कि यह अब तक नहीं मिली है। इसके बजाए, स्क्रिप्ट संकलन के दौरान स्क्रिप्ट विफल हो जाती है, इससे पहले कि मेरी दिनचर्या को भी बुलाया जाए। इस प्रकार स्क्रिप्ट का उपयोगकर्ता कुछ बहुत अस्पष्ट सिंटैक्स त्रुटि ट्रेसबैक देखता है - जिसके लिए बहुत जरूरी है कि एक विशेषज्ञ को यह कटौती करनी पड़े कि यह केवल पायथन के गलत संस्करण को चलाने का मामला है।

मुझे पता है कि पायथन के संस्करण की जांच कैसे की जाती है। मुद्दा यह है कि पायथन के पुराने संस्करणों में कुछ सिंटैक्स अवैध है। इस कार्यक्रम पर विचार करें:

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

(सहकर्मी के लिए चैनल करना।)


3
"अजगर के संस्करण की जाँच करें। मुद्दा यह है कि अजगर के पुराने संस्करणों में कुछ वाक्यविन्यास अवैध है।" मुझे नहीं पता कि यह कैसे समस्या है। यदि आप संस्करण की जांच कर सकते हैं, तो आप सिंटैक्स त्रुटि से बच सकते हैं। सिंटैक्स पर संस्करण की जाँच कैसे लागू नहीं होती है? क्या आप अपना प्रश्न स्पष्ट कर सकते हैं?
S.Lott

4
@ S.Lott नहीं, आप गलत नहीं हैं, यह सिर्फ इतना है कि कठिनाई कोड को शामिल करने में है जहां इसे पढ़ा नहीं जाएगा (पार्स किया गया) और साथ ही निष्पादित नहीं किया गया - यह उत्तर दिखाने के तुरंत बाद स्पष्ट नहीं है।
ब्रेंडन

7
S.Lott, आप अपने परीक्षण को अजगर के पुराने संस्करण में निष्पादित नहीं कर सकते क्योंकि यह संकलन नहीं करता है। इसके बजाय, आपको एक सामान्य सिंटैक्स त्रुटि मिलती है। 2.4 इंटरप्रेटर के साथ उदाहरण कोड का प्रयास करें और आप देखेंगे कि आप संस्करण परीक्षण के लिए नहीं पहुंच सकते हैं।
मार्क हैरिसन

7
@ S.Lott खैर यह इस बात पर निर्भर करता है कि आप क्या तुच्छ मानते हैं - व्यक्तिगत रूप से मैं पायथन के विभिन्न संस्करणों के लिए अलग-अलग फाइलें बनाने या अतिरिक्त प्रक्रियाओं को तुच्छ बनाने पर विचार नहीं करूंगा। मैं कहूंगा कि यह प्रश्न मूल्यवान है, खासकर जब आप पायथन को स्वच्छ और अक्सर आश्चर्यजनक चाल से भरा मानते हैं - मैं Google से यहां आया था ताकि यह जानना चाहूं कि क्या कोई साफ जवाब था
ब्रेंडन

7
मुझे लगता है कि हम इस चर्चा के अंत तक पहुँच चुके हैं। मैंने कुछ के बारे में एक सवाल पूछा, जो मुझे नहीं पता था कि मुझे कैसे करना है, और मुझे एक उत्तर मिला कि मुझे यह कैसे करना है। मैं कुछ भी प्रस्तावित नहीं कर रहा हूं, मैंने सिर्फ ओर्पी के उत्तर को स्वीकार किया है जो मेरे लिए बहुत अच्छा काम कर रहा है (वास्तव में सहकर्मी जिनके लिए मैं चैनल कर रहा हूं)। विवा ले स्टैक ओवरफ्लो!
मार्क हेरिसन

जवाबों:


111

आप का उपयोग कर परीक्षण कर सकते हैं eval:

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

इसके अलावा, with है अजगर 2.5 में, बस जोड़ने उपलब्ध from __future__ import with_statement

EDIT: पर्याप्त रूप से नियंत्रण प्राप्त करने के लिए, आप इसे विभिन्न .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 *

10
यह एक शानदार जवाब है। प्रश्न से मुख्य मुद्दा जो संबोधित करने की आवश्यकता है, वह यह है कि एक प्रोग्राम को सिंथैटिक रूप से सही करना चाहिए, जो कि अजगर के उस संस्करण के लिए भी निष्पादित करना शुरू कर सकता है, इसलिए नए सिंटैक्स का उपयोग करना इंटरप्रेटर के पुराने संस्करणों पर शुरू होने से एक प्रोग्राम को रोकता है। इसके आसपास काम करता है
ऑटोप्लेक्टिक

7
यदि पैकेज को सेटप्टूल द्वारा स्थापित किया जा रहा है, तो स्रोत फ़ाइलों को बाइट-कंपाइल करना तब विफल हो जाएगा। इसके अलावा, रन-टाइम एरर मैसेज का उत्पादन करने के लिए सभी कंट्रोवर्सी थोड़ी निरर्थक लगती हैं - क्यों न केवल आवश्यकताओं का दस्तावेज़ीकरण किया जाए और इसे उस पर छोड़ दिया जाए?
जॉन माकिन

2
ध्यान दें कि यदि एक साधारण कथन के बजाय एक अभिव्यक्ति की जांच करने का प्रयास किया जाए, तो आपको execइसके बजाय उपयोग करने की आवश्यकता है eval। मैं एक ऐसा फ़ंक्शन लिखने की कोशिश कर रहा था, जो py2k और py3k दोनों में stderr पर प्रिंट होगा।
Xiong Chiamiov

2
मुझे लगता है कि इस समाधान का एक क्लीनर संस्करण आपके "चेक" को एक अलग मॉड्यूल में डाल देगा और आयात करेगा ( importस्टेशन को प्रयास में / छोड़कर लपेटें )। ध्यान दें कि आपको अन्य चीज़ों के लिए भी जाँच करने की आवश्यकता हो सकती है SyntaxError(जैसे। मानक पुस्तकालय के लिए निर्मित कार्य या परिवर्धन)
स्टीवन

103

अपने कार्यक्रम के चारों ओर एक आवरण रखें जो निम्न कार्य करता है।

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 पायथन दुभाषियों का उपयोग कर रहे हैं, लेकिन तब आपके पास कुछ नियमित अभिव्यक्ति करने के लिए है।

और ऐसा करने के लिए और अधिक सुरुचिपूर्ण तरीके हो सकते हैं।


7
FYI करें, "cur_version> = req_version" को सशर्त के रूप में काम करना चाहिए।
orip

4
sys.version_infoकोई फ़ंक्शन नहीं है।
nh2

3
कोड को सफल स्थिति के अंदर रखना जैसे कि यह बहुत बुरा अभ्यास है क्योंकि यह एक आवश्यक इंडेंटेशन और तर्क के अतिरिक्त है। बस एक: अगर sys.version_info [: 2] <req_version: "पुराना" प्रिंट करें; sys.exit () - और अन्यथा हमेशा की तरह जारी रखें।
टिम

1
यह ऐसा है जैसे टिम पीटर्स "द ज़ेन ऑफ पायथन" में कहते हैं: "फ्लैट नेस्टेड से बेहतर है।" (आप अजगर में "इस आयात" टाइप करके इसे देख सकते हैं)
क्रिस्टोफर Shroba

1
@ChristopherShroba आपको धन्यवाद import this। एक प्यारा मोड़।
शमूएल हरमर

32

प्रयत्न

आयात मंच
platform.python_version ()

आपको "2.3.1" जैसी स्ट्रिंग देनी चाहिए। यदि यह वास्तव में वैट नहीं है, तो आप "प्लेटफ़ॉर्म" बिल्ड-इन के माध्यम से उपलब्ध डेटा का एक समृद्ध सेट चाहते हैं। आप जो चाहते हैं, वह कहीं होना चाहिए।


4
-1: यह काम नहीं करता है, जैसा कि अद्यतन प्रश्न में बताया गया है। यदि आप पायथन के एक नए संस्करण से किसी भी वाक्यविन्यास का उपयोग करते हैं तो आपकी फ़ाइल संकलित नहीं होगी, और यदि वह संकलन नहीं करती है तो वह संस्करण को चला नहीं सकती है और न ही जांच सकती है!
स्कॉट ग्रिफ़िथ्स

1
print(platform.python_version())इसके बजाय @ScottGriffiths चलाएं platform.python_version()!
सूर्या

@ScottGriffiths मेरा उत्तर भी चेकआउट करें: stackoverflow.com/a/40633458/5157221
सूर्या

22

संभवत: इस संस्करण की तुलना करने का सबसे अच्छा तरीका इसका उपयोग करना है sys.hexversion। यह महत्वपूर्ण है क्योंकि संस्करण टुपल्स की तुलना करने से आपको सभी अजगर संस्करणों में वांछित परिणाम नहीं मिलेगा।

import sys
if sys.hexversion < 0x02060000:
    print "yep!"
else:
    print "oops!"

मुझे लगता है कि यह सबसे सुरुचिपूर्ण है, लेकिन शायद अन्य देवों द्वारा समझने में सबसे आसान नहीं है।
निक बोल्टन

5
क्या आप बता सकते हैं कि किन परिस्थितियों में संस्करण ट्यूपल्स की तुलना वांछित परिणाम नहीं देगी?
स्पूनमाइजर

संस्करण tuples में अल्फ़ान्यूमेरिक मान भी हो सकते हैं।
१२:२२

8
-1: यह काम नहीं करता है, जैसा कि अद्यतन प्रश्न में बताया गया है। यदि आप पायथन के एक नए संस्करण से किसी भी वाक्यविन्यास का उपयोग करते हैं तो आपकी फ़ाइल संकलित नहीं होगी, और यदि वह संकलन नहीं करती है तो वह संस्करण को चला नहीं सकती है और न ही जांच सकती है!
स्कॉट ग्रिफ़िथ्स

किस संस्करण / प्लेटफ़ॉर्म पर यह विफल होता है?
सोरिन

15
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")

7
ध्यान रखें कि अजगर 2.6 और नीचे में, हो सकता है sys.version_infoहै नहीं एक नामित टपल। आपको sys.version_info[0]प्रमुख संस्करण संख्या और sys.version_info[1]लघु के लिए उपयोग करना होगा ।
coredumperror

9

AskUbuntu में Nykakin से जवाब :

आप platformमानक पुस्तकालय से मॉड्यूल का उपयोग करके स्वयं कोड से पायथन संस्करण भी देख सकते हैं ।

दो कार्य हैं:

  • platform.python_version() (रिटर्न स्ट्रिंग)।
  • platform.python_version_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')

विंडोज 10 पर एक WAMP सर्वर के माध्यम से CGI के साथ पायथन का उत्पादन:

स्क्रीनशॉट 2016-11-16 14.39.01 को सुरिया कुदो द्वारा


सहायक संसाधन


7

पीठ पीछे संगत रहने के लिए सेट्स पायथन 2.4 में मुख्य भाषा का हिस्सा बन गए। मैंने इसे वापस किया, जो आपके लिए भी काम करेगा:

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

3
संस्करण के बजाय सुविधा के लिए जांचना बेहतर है, नहीं? try: set except NameError: from sets import Set as set
ऑप सिप

@orip: क्यों? यदि आप जानते हैं कि किस संस्करण में एक सुविधा शुरू की गई है, तो यहां सेट की तरह, बस ऊपर दिए गए कोड का उपयोग करें। कुछ गलत नहीं है उसके साथ।
एंड्रे

7

हालांकि सवाल यह है: मैं एक त्रुटि संदेश जारी करने और बाहर निकलने के लिए पर्याप्त नियंत्रण कैसे प्राप्त करूं ?

मेरे द्वारा दिए गए प्रश्न का उत्तर यह है: ऐप शुरू करने से पहले मैं एक त्रुटि संदेश जारी करने के लिए पर्याप्त नियंत्रण कैसे प्राप्त करूं ?

मैं इसे बहुत अलग तरीके से जवाब दे सकता हूं फिर अन्य पोस्ट। लगता है कि अब तक के जवाब पायथन के भीतर से आपके प्रश्न को हल करने की कोशिश कर रहे हैं।

मैं कहता हूं, पायथन लॉन्च करने से पहले संस्करण की जाँच करें। मैं देख रहा हूं कि आपका मार्ग लिनक्स या यूनिक्स है। हालाँकि मैं आपको केवल एक Windows स्क्रिप्ट की पेशकश कर सकता हूं। मुझे लगता है कि यह linux स्क्रिप्टिंग वाक्यविन्यास के लिए adapting छवि बहुत कठिन नहीं होगा।

यहाँ संस्करण 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

यह आपके आवेदन के किसी भी भाग को नहीं चलाता है और इसलिए पायथन अपवाद को नहीं बढ़ाएगा। यह कोई अस्थायी फ़ाइल नहीं बनाता है और न ही कोई OS वातावरण चर जोड़ता है। और यह आपके एप्लिकेशन को अलग-अलग संस्करण सिंटैक्स नियमों के कारण अपवाद के रूप में समाप्त नहीं करता है। यह तीन कम संभव सुरक्षा बिंदु हैं।

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

और मेरा हैक संस्करण:

[एमएस स्क्रिप्ट; पायथन संस्करण पाइथन मॉड्यूल के प्रीलांच की जांच करता है] http://pastebin.com/aAuJ91FQ


उन वोटों के लिए कृपया कारण बताने से न डरें।
DevPlayer

वास्तव में मैं देख रहा था। धन्यवाद! ह% द% ह?
क्लॉक

@Clocker python.exe -V "पायथन 2.7" स्ट्रिंग लौटाएगा। कंसोल "पायथन" स्ट्रिंग को %% G में और "2.7" स्ट्रिंग को स्वचालित रूप से बनाए गए os var %% H (G के बाद अगला अक्षर) में रखता है। इको %% H | DOS कमांड में "2.7" पाइप "2.7" ढूंढें "2.7" जो "% 2.7 "में %% H पाया जाता है, तो त्रुटि स्तर 1 पर सेट करता है। वह त्रुटि स्तर, जिसके परिणामस्वरूप 1, DOS खोज आदेश का उपयोग करने से, हमें DOS बैच लेबल की शाखा करने की अनुमति देगा: Python27
DevPlayer

3
import sys
sys.version

इस तरह जवाब मिल जाएगा

'2.7.6 (डिफ़ॉल्ट, 26 अक्टूबर 2016, 20:30:19) \ n [जीसीसी 4.8.4]'

यहाँ 2.7.6 संस्करण है


2

जैसा कि ऊपर उल्लेख किया गया है, वाक्यविन्यास त्रुटियां संकलन समय पर होती हैं, रन टाइम पर नहीं। जबकि पायथन एक "व्याख्या की गई भाषा" है, जबकि पायथन कोड वास्तव में सीधे व्याख्या नहीं है; यह बाइट कोड के लिए संकलित है, जो तब व्याख्या की जाती है। एक संकलन चरण है जो तब होता है जब एक मॉड्यूल आयात किया जाता है (यदि कोई .pyc या orpyd फ़ाइल के रूप में कोई पहले से संकलित संस्करण उपलब्ध नहीं है) और वह यह है कि जब आप अपनी त्रुटि प्राप्त कर रहे हों, तब (बिल्कुल ठीक नहीं)। आपका कोड चल रहा है।

आप संकलित चरण को बंद कर सकते हैं और कोड की एक पंक्ति के लिए रन टाइम पर ऐसा कर सकते हैं, यदि आप चाहें, तो उपरोक्त के रूप में, eval का उपयोग करके, लेकिन मैं व्यक्तिगत रूप से ऐसा करने से बचना पसंद करता हूं, क्योंकि यह पायथन को संभावित रूप से प्रदर्शन करने का कारण बनता है। अनावश्यक रन-टाइम संकलन, एक चीज़ के लिए, और दूसरे के लिए, यह बनाता है कि मुझे क्या लगता है कोड अव्यवस्था। (यदि आप चाहें, तो आप उस कोड को उत्पन्न कर सकते हैं जो कोड उत्पन्न करता है - और यह अब से 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 (cond, a, b) जैसे वाक्य रचना की एक पंक्ति के साथ एक फ़ंक्शन भी लिख सकता हूं।)

एक और बात जो इंगित करने लायक हो सकती है (कि मैं थोड़ा हैरान हूं कि किसी ने अभी तक ध्यान नहीं दिया है) वह यह है कि जबकि पायथन के पहले के संस्करणों ने कोड का समर्थन नहीं किया था

value = 'yes' if MyVarIsTrue else 'no'

..इस तरह सपोर्ट कोड किया

value = MyVarIsTrue and 'yes' or 'no'

वह तीखा भाव लिखने का पुराना तरीका था। मेरे पास अभी तक पायथन 3 स्थापित नहीं है, लेकिन जहां तक ​​मुझे पता है, कि "पुराना" तरीका अभी भी इस दिन के लिए काम करता है, इसलिए आप अपने लिए यह तय कर सकते हैं कि क्या यह नए सिंटैक्स का सशर्त उपयोग करने के लिए है या नहीं, अगर आपको ज़रूरत है पायथन के पुराने संस्करणों के उपयोग का समर्थन करने के लिए।


2
गंभीरता से? अपना कोड डुप्लिकेट करें ताकि आप कुछ छोटी संरचनाओं को बदल सकें? छी। बहुत चिल्लाता है। और a and b or cइसके बजाय के रूप में b if a else c, यह बराबर नहीं है; अगर bयह गलत है तो यह विफल हो जाएगा, aबजाय उत्पादन b
क्रिस मॉर्गन

1
मैं कोड डुप्लिकेट करने का सुझाव नहीं दे रहा हूं, मैं सुझाव दे रहा हूं कि संस्करण-विशिष्ट कोड के लिए आवरण कार्य बना रहा हूं, जिनके हस्ताक्षर संस्करणों में नहीं बदलते हैं, और उन कार्यों को संस्करण-विशिष्ट मॉड्यूल में डालते हैं। मैं उन कार्यों के बारे में बात कर रहा हूं जो शायद 1 से 5 लाइनें लंबी हैं। यह सही है कि a और b या c, b के समान नहीं है यदि a और c उन मामलों में जहां b गलत का मूल्यांकन कर सकता है। इसलिए मुझे लगता है कि अगर IAThenBElseC (a, b, c) को आम___2_4.py, 1 के बजाय 2 या 3 लाइन लंबी होगी, तो यह विधि वास्तव में सामान्य मुहावरों को फ़ंक्शन में संलग्न करके आपके सभी कोड को कम कर देती है।
शाविस

2

अपनी फ़ाइल के शीर्ष पर निम्नलिखित रखें:

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...

1
बल्कि उपयोग करेंsys.version_info < (2, 7)
एंटटी हवाला

@AnttiHaapala यह मेरे लिए एकदम सही है, क्या आप बता सकते हैं कि sys.version_infoटपल के काम करने के प्रकार की तुलना क्यों की जाती है ?
jjj

@jjj sys.version_info हुआ करता था एक टपल; उदाहरण के लिए (2, 4, 6, 'final', 0); केवल पायथन 3 और 2.7 में ही इसे एक अलग प्रकार में बदल दिया गया था, जो फिर भी टुपल्स के साथ तुलनीय है।
अंती हापला

@AnttiHaapala मुझे उस दृष्टिकोण से अच्छा लगता है ... धन्यवाद!
jml

1

मुझे लगता है कि सबसे अच्छा तरीका संस्करणों के बजाय कार्यक्षमता के लिए परीक्षण करना है। कुछ मामलों में, यह तुच्छ है, दूसरों में ऐसा नहीं है।

उदाहरण के लिए:

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

जब तक आप कोशिश कर रहे हैं / ब्लॉकों को छोड़कर उपयोग करने में पर्याप्त हैं, आप अपने अधिकांश ठिकानों को कवर कर सकते हैं।


2
आप सही हे। यही कारण है कि उसने पूछा कि कैसे करना है - कभी-कभी संस्करण वाई में सुविधाओं के लिए परीक्षण भी संस्करण X में बायटेकोड के लिए संकलित नहीं करता है, इसलिए इसे सीधे नहीं किया जा सकता है।
-09

1

मुझे बस इस सवाल का पता चला एक त्वरित खोज के बाद समस्या को हल करने की कोशिश करते हुए और मैं ऊपर दिए गए कुछ सुझावों के आधार पर एक हाइब्रिड के साथ आया हूं।

मुझे एक रैपर स्क्रिप्ट का उपयोग करने का देवपैलर का विचार पसंद है, लेकिन नकारात्मक पक्ष यह है कि आप अलग-अलग OSes के लिए कई आवरणों को बनाए रखते हैं, इसलिए मैंने रैपर को अजगर में लिखने का फैसला किया, लेकिन उसी बुनियादी "संस्करण का उपयोग करें" exe "तर्क के साथ पकड़ो" और इसके साथ आया।

मुझे लगता है कि इसे 2.5 और बाद के लिए काम करना चाहिए। मैंने इसे 2.66, 2.7.0 और 3.1.2 लिनक्स पर और 2.6.1 ओएस एक्स पर अब तक परीक्षण किया है।

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") )

हां, मुझे पता है कि अंतिम डिकोड / स्ट्रिप लाइन भयानक है, लेकिन मैं सिर्फ संस्करण संख्या को जल्दी से पकड़ना चाहता था। मैं उसे निखारने जा रहा हूं।

यह मेरे लिए अभी के लिए काफी अच्छा काम करता है, लेकिन अगर कोई इसमें सुधार कर सकता है (या मुझे बताएं कि यह एक भयानक विचार क्यों है) तो यह भी अच्छा होगा।


1

के लिए स्टैंडअलोन अजगर स्क्रिप्ट, निम्नलिखित मॉड्यूल docstring चाल एक अजगर संस्करण (यहां v2.7.x) (* nix पर परीक्षण) काम करता है लागू करने के लिए।

#!/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
[...]

यह लापता अजगर को निष्पादन योग्य के रूप में अच्छी तरह से संभालना चाहिए लेकिन जीआरपी पर निर्भरता है। पृष्ठभूमि के लिए यहां देखें ।


0

के साथ sys.hexversionया जाँच कर सकते हैं sys.version_info

sys.hexversion बहुत मानव-अनुकूल नहीं है क्योंकि यह एक हेक्साडेसिमल संख्या है। sys.version_infoएक तुच्छ है, इसलिए यह अधिक मानव-अनुकूल है।

अजगर 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 भले ही कम मानव-हितैषी हो, लेकिन ।

मैं आशा करता हूं कि इससे आपको मदद मिली होगी!


0

मैं एखन के उत्कृष्ट उत्तर पर विस्तार कर रहा हूं, जो कि पायथन लिपि से पहले भी एक सहायक संदेश को संकलित करता है।

यदि आप यह सुनिश्चित करना चाहते हैं कि स्क्रिप्ट पायथन 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:), और उचित ईएक्सक्यूट अनुमति बिट्स सेट के साथ।


-2

इस बारे में कैसा है:

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

5
-1: यह काम नहीं करता है, जैसा कि अद्यतन प्रश्न में बताया गया है। यदि आप पायथन के एक नए संस्करण से किसी भी वाक्यविन्यास का उपयोग करते हैं तो आपकी फ़ाइल संकलित नहीं होगी, और यदि वह संकलन नहीं करती है तो वह संस्करण को चला नहीं सकती है और न ही जांच सकती है!
स्कॉट ग्रिफ़िथ्स

-3

समस्या काफी सरल है। आपने जाँच की कि संस्करण 2.4 से कम था , उससे कम या उसके बराबर नहीं । इसलिए यदि पायथन संस्करण 2.4 है, तो यह 2.4 से कम नहीं है। आपको क्या करना चाहिए था:

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

, नहीं

    if sys.version_info < (2, 4):

4
अनुच्छेद 3, और अद्यतन पढ़ें। यदि आप नई भाषा के निर्माण का उपयोग कर रहे हैं तो आप इस कोड को निष्पादित करने की बात नहीं करेंगे क्योंकि आपका कोड 2.4 पर संकलित नहीं होगा।
मार्क हैरिसन

कम से कम ठीक था, बस eval गायब है।
क्रेग
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.