जाँच रहा है अगर sys.argv [x] परिभाषित है


104

अगर स्क्रिप्ट के लिए एक चर पास किया गया था, तो यह जांचने का सबसे अच्छा तरीका क्या होगा:

try:
    sys.argv[1]
except NameError:
    startingpoint = 'blah'
else:
    startingpoint = sys.argv[1]

जवाबों:


64

अंत में, बीच का अंतर try, exceptऔर परीक्षण len(sys.argv)सभी महत्वपूर्ण नहीं है। वे दोनों की तुलना में थोड़ा हैकिश हैंargparse ।

यह मेरे लिए होता है, हालांकि - कम बजट के एक प्रकार के झगड़े के रूप में:

arg_names = ['command', 'x', 'y', 'operation', 'option']
args = dict(zip(arg_names, sys.argv))

आप इसका उपयोग namedtupleउन मानों को उत्पन्न करने के लिए भी कर सकते हैं, जो डिफ़ॉल्ट रूप से None- सभी चार लाइनों में!

Arg_list = collections.namedtuple('Arg_list', arg_names)
args = Arg_list(*(args.get(arg, None) for arg in arg_names))

यदि आप इससे परिचित नहीं हैं namedtuple, तो यह सिर्फ एक टपल है जो ऑब्जेक्ट की तरह काम करता है, जिससे आप tup.attributeसिंटैक्स के बजाय सिंटैक्स का उपयोग करके इसके मूल्यों को एक्सेस कर सकते हैं tup[0]।

तो पहली पंक्ति namedtupleप्रत्येक मान के लिए मानों के साथ एक नया प्रकार बनाती है arg_names। दूसरी पंक्ति argsशब्दकोश से मानों को पारित करती है , getडिफ़ॉल्ट मान वापस करने के लिए जब दिए गए तर्क नाम का शब्दकोश में संबद्ध मूल्य नहीं होता है।


मैं अजगर को अधिक से अधिक प्यार करता हूं, सभी इस तरह के उत्तर के लिए धन्यवाद और स्टैक ओवरफ्लो! बहुत बुरा हम पिछले दो लाइनों की व्याख्या नहीं है। मेरा मानना ​​है कि शुरुआती लोगों के लिए यह बहुत अच्छा होगा।
— गोजोन

2
इसे प्यार करना! आसानी से सबसे अच्छा समाधान मैंने इस समस्या को देखा है। दूसरों के लिए: यह मेरे लिए तुरंत स्पष्ट नहीं था (newb) कि: 1) 'कमांड' हर बार पहले तर्क के रूप में पास होगा और 2) आप args [0] आदि के साथ परिणाम कॉल कर सकते हैं
— मैट डी

यह सुनिश्चित करने के लिए अच्छा है, लेकिन लंबाई के परीक्षण के बारे में क्या हैक है?
— कलरलैस

1
@timwiz मैं केवल argparse का उपयोग करने की तुलना में बोल रहा था। फिर भी, इन दिनों, मैं हर बार अपने आप को लात मारता हूं जब भी मैं एक पुरानी पटकथा पर वापस आता हूं और पाता हूं कि मैंने किसी तरह का विवाद नहीं किया।
— प्रेषित

116

की लंबाई की जाँच करें sys.argv:

if len(sys.argv) > 1:
    blah = sys.argv[1]
else:
    blah = 'blah'

कुछ लोग आपके द्वारा सुझाए गए अपवाद-आधारित दृष्टिकोण (जैसे try: blah = sys.argv[1]; except IndexError: blah = 'blah') को पसंद करते हैं , लेकिन मुझे यह उतना पसंद नहीं है क्योंकि यह "स्केल" लगभग नहीं है (जैसे, जब आप दो या तीन तर्क स्वीकार करना चाहते हैं) और यह संभावित रूप से त्रुटियों को छिपा सकता है (उदाहरण के लिए, यदि आप उपयोग करते हैं blah = foo(sys.argv[1]), लेकिन foo(...)उठाया IndexError, IndexErrorतो इसे नजरअंदाज कर दिया जाएगा)।


1
जब तक आप इसके बारे में परमाणु हो रहे हैं, तब तक चिंता की कोई बात नहीं है try, except। बस fooअपने तर्क की प्रतीक्षा करें जब तक कि elseखंड न हो जाए।
— प्रेषक

3
इसके अलावा, एक बार जब आप स्केलिंग के बारे में सोच रहे हैं, यह समय के लिए आगे बढ़ना है argparse।
— प्रेषक

1
अर्गपर्स पर +1। मैं अपने argparse.pyसभी कमांड-लाइन प्रोजेक्ट्स में मिल गया हूं।
— डेविड वोलेवर

2
@ प्रमाण: निश्चित रूप से, यदि आप इसके बारे में मेहनती हैं, तो यह ठीक है। लेकिन मेरे अनुभव में अधिकांश प्रोग्रामर मेहनती नहीं हैं और सभी तर्क को tryखंड में रख देते हैं ... इसलिए, यह देखते हुए कि यह कठिन नहीं है (और, IMO, थोड़ा प्रेटियर), मैं सिर्फ लंबाई की जांच करना पसंद करता हूं (और भी, आप लोग होने से बचते हैं प्रवाह नियंत्रण के लिए अपवादों का उपयोग करने के लिए आप पर चिल्लाते हैं)।
— डेविड वोलेवर

2
@ डेविड, हाँ, मैं आपकी बात देख रहा हूँ। मैं tryमाफी माँगने वाला हूँ , मुझे मानना ​​होगा। मुझे बस लगता है कि यह कभी-कभी एक ifबयान की तुलना में मेरे इरादे को अधिक स्पष्ट रूप से व्यक्त करता है।
— प्रेषि।

22

दूसरा तरीका जो मैंने अभी तक सूचीबद्ध नहीं देखा है, वह है समय से पहले अपना प्रहरी मूल्य निर्धारित करना। यह विधि पायथन के आलसी मूल्यांकन का लाभ उठाती है, जिसमें आपको हमेशा एक elseबयान देने की आवश्यकता नहीं होती है । उदाहरण:

startingpoint = 'blah'
if len(sys.argv) >= 2:
  startingpoint = sys.argv[1]

या अगर आप वाक्य रचना CRAZY जा रहे हैं तो आप पायथन के टर्नरी ऑपरेटर का उपयोग कर सकते हैं :

startingpoint = sys.argv[1] if len(sys.argv) >= 2 else 'blah'

1
टेनेरी ऑपरेटर का जवाब मेरी आँखों के लिए सबसे सुंदर है। मैं यहाँ चुपचाप इस तथ्य को कोस रहा हूँ कि मेरे द्वारा बनाए गए कुछ सॉफ्टवेयर पायथन 2.4 से बँधे हुए हैं, जिनमें यह नहीं है।
— रिचर्ड बैरेल

11

मैं इसका उपयोग करता हूं - यह कभी विफल नहीं होता है:

startingpoint = 'blah'
if sys.argv[1:]:
   startingpoint = sys.argv[1]

परिभाषित करने के लिए जाँच नहीं है। यदि मौजूद है तो अधिक परिभाषित है, जो समान नहीं है। मैंने उस तरीके का उपयोग फ़ॉलबैक चर को आश्वस्त करने के लिए भी किया है, लेकिन वर्तमान प्रश्न का उत्तर नहीं है।
— m3nda

@ erm3nda मैं startingpointवेरिएबल को उदाहरण से हटा सकता हूं , लेकिन सवाल एक फालबैक वेरिएबल को असाइन कर रहा है, इसलिए मैंने सिर्फ वही बनाया है।
— अनातोली टेकटोनिक

1
यदि आप इसे हटाते हैं तो आपको चर के बारे में एक त्रुटि मिलेगी जो परिभाषित नहीं है। मैंने प्रश्न को फिर से पढ़ा है, और वह क्या उम्मीद करता है कि, एक चर प्रतिस्थापन :) तो यह ठीक है। उस छोटे तरीके की सलाह के लिए धन्यवाद अगर sys.argv[1:]:। यह स्थितिगत तर्कों के साथ काम करता है जबकि गिनती नहीं करता है।
— m3nda

10

यह एक साधारण अजगर की सूची है। इसके लिए आप जो अपवाद पकड़ेंगे, वह IndexError है, लेकिन आप इसके बजाय केवल लंबाई की जांच कर रहे हैं।

if len(sys.argv) >= 2:
  startingpoint = sys.argv[1]
else:
  startingpoint = 'blah'

2

नक्शे के साथ काम करने वाला एक समाधान निर्मित फोंशन में!

arg_names = ['command' ,'operation', 'parameter']
args = map(None, arg_names, sys.argv)
args = {k:v for (k,v) in args}

फिर आपको बस अपने मापदंडों को इस तरह से कॉल करना होगा:

if args['operation'] == "division":
    if not args['parameter']:
        ...
    if args['parameter'] == "euclidian":
        ...

1

आप बस argv के लिए argv [1] का मान जोड़ सकते हैं और फिर जाँच सकते हैं कि argv [1] आपके द्वारा इनपुट किए गए स्ट्रिंग के बराबर नहीं है:

from sys import argv
argv.append('SomeString')
if argv[1]!="SomeString":
            print(argv[1])

उन लोगों के लिए जिन्होंने मुझे वोट दिया, गलती को स्पष्ट नहीं करने के लिए आप पर शर्म की बात है।
— हसन अब्दुल-करीम

मुझे लगता है कि यह हैकिश है। क्या होगा अगर कोई किसी को तर्क के रूप में पास करता है? कैसे उपयोग करें कि यदि आप स्वीकार कर सकते हैं तो 1 से 5 तर्क दें?
— pbogut

उपयोगकर्ता द्वारा तर्क की आपूर्ति नहीं करने की स्थिति में एक डिफ़ॉल्ट मान सेट करने के लिए कूल (लेकिन अभी भी हैकिश)। बस संलग्न करें और फिर argv [1] का उपयोग करें।
— फेलिजेट

1

मूल प्रवर्तक जो करने की कोशिश कर रहा था, उसके बहुत करीब है। यहां एक फ़ंक्शन है जिसका मैं उपयोग करता हूं:

def get_arg(index):
    try:
        sys.argv[index]
    except IndexError:
        return ''
    else:
        return sys.argv[index]

तो एक उपयोग कुछ इस तरह होगा:

if __name__ == "__main__":
    banner(get_arg(1),get_arg(2))
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.