Sys.argv [এক্স] সংজ্ঞায়িত করা হয়েছে কিনা তা পরীক্ষা করা হচ্ছে


106

স্ক্রিপ্টটির জন্য কোনও ভেরিয়েবল পাস করা হয়েছে কিনা তা যাচাই করার সর্বোত্তম উপায় কী হবে:

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যখন প্রদত্ত আর্গুমেন্টের নামের অভিধানের সাথে যুক্ত মান থাকে না তখন ডিফল্ট মান ফেরত দিতে ব্যবহার করে।


আমি পাইথনকে আরও বেশি ভালবাসি, এর মতো উত্তরের জন্য সমস্ত ধন্যবাদ এবং অবশ্যই স্ট্যাক ওভারফ্লো! খুব খারাপ আমাদের শেষ দুটি লাইনের ব্যাখ্যা নেই। আমি বিশ্বাস করি নতুনদের জন্য যা দুর্দান্ত হবে।
গৌজন

4
এটা ভালবাসা! সহজেই সবচেয়ে ভাল সমাধান আমি এই সমস্যাটি দেখেছি। অন্যদের জন্য: এটা আমার কাছে তাত্ক্ষণিকভাবে স্পষ্ট ছিল না যে: (১) 'কমান্ড' প্রতিবার প্রথম যুক্তি হিসাবে পাস হবে এবং ২) আপনি আর্গুমেন্টগুলি দিয়ে ফলাফল কল করতে পারেন [0] ইত্যাদি
ম্যাট ডি

এটি নিশ্চিতভাবে দুর্দান্ত, তবে দৈর্ঘ্য পরীক্ষার বিষয়ে হকি কী?
রঙিন করুন

4
@ টিটিউইজ আমি কেবল আরগপার্স ব্যবহারের তুলনায় বলছিলাম। তবুও, আজকাল আমি যখনই পুরানো স্ক্রিপ্টে ফিরে আসি তখন নিজেকে লাথি মেরে দেখি আরগপার্স ব্যবহার করা হয়নি।
প্রেরক

120

এর দৈর্ঘ্য পরীক্ষা করুন 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উপেক্ষা করা হবে)।


4
যতক্ষণ আপনি এটি সম্পর্কে পারমাণবিক হচ্ছেন ততক্ষণ, এটি নিয়ে উদ্বিগ্ন হওয়ার কিছু নেই try, except। ক্লজ fooঅবধি আপনার যুক্তির জন্য অপেক্ষা করুন else
প্রেরক

4
এছাড়াও, আপনি একবার স্কেলিং সম্পর্কে চিন্তাভাবনা করার পরে, এটির উপরে চলে যাওয়ার সময় argparse
প্রেরক

4
আরগপার্সে +1। আমি argparse.pyআমার সমস্ত কমান্ড-লাইন প্রকল্পে পেয়েছি ।
ডেভিড ওলবার

4
@ সেন্ডারেল: অবশ্যই, আপনি যদি এ ব্যাপারে পরিশ্রমী হন তবে তা ঠিক আছে। তবে আমার অভিজ্ঞতার সাথে বেশিরভাগ প্রোগ্রামাররা পরিশ্রমী না হয়ে সমস্ত যুক্তি যুক্ত করে দেয় try... সুতরাং, এটি কোনও কঠিন (এবং, আইএমও, কিছুটা সুন্দর) না রেখে, আমি কেবল দৈর্ঘ্য পরীক্ষা করতে পছন্দ করি (এছাড়াও, আপনি লোকজন এড়াতে চান) প্রবাহ নিয়ন্ত্রণের জন্য ব্যতিক্রমগুলি ব্যবহার করার জন্য আপনাকে চিৎকার করবে)।
ডেভিড ওলবার

4
@ ডেভিড, হ্যাঁ, আমি আপনার বক্তব্যটি দেখতে পাচ্ছি। আমি কিছুটা 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'

4
তিনটি অপারেটরের উত্তরটি আমার চোখের কাছে সবচেয়ে সুন্দর। আমি এখানে বসে চুপচাপ এই কথাটি অভিশাপ দিচ্ছি যে আমি যে সফ্টওয়্যারটি রক্ষণ করি সেগুলির কয়েকটি পাইথন ২.৪ এর সাথে আবদ্ধ, যা এটি নেই।
রিচার্ড ব্যারেল

12

আমি এটি ব্যবহার করি - এটি কখনই ব্যর্থ হয় না:

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

এটি সংজ্ঞাযুক্ত কিনা তা যাচাই করার জন্য নয়। আরও উপস্থিত থাকলে সংজ্ঞায়িত করার মতো, যা একই নয় the আমি ফ্যালব্যাক ভেরিয়েবলগুলি আশ্বস্ত করতেও সেভাবে ব্যবহার করেছি, তবে বর্তমান প্রশ্নের উত্তর নয়।
এম 3 এন্ড

@ erm3nda আমি startingpointউদাহরণ থেকে পরিবর্তনশীল অপসারণ করতে পারি , তবে প্রশ্নটি একটি ফ্যালব্যাক ভেরিয়েবল বরাদ্দ করছে, তাই আমি কেবল এটি তৈরি করেছি।
অ্যান্টোলি টেকটোনিক

4
আপনি যদি এটি অপসারণ করেন তবে আপনি ভেরিয়েবলের সংজ্ঞা না দেওয়া সম্পর্কিত একটি ত্রুটি পাবেন। আমি আবার প্রশ্নটি পড়েছি, এবং তার কী প্রত্যাশা তা হ'ল, একটি পরিবর্তনশীল প্রতিস্থাপন :) তাই ঠিক আছে। যদি সংক্ষিপ্ত পথে পরামর্শের জন্য আপনাকে ধন্যবাদ sys.argv[1:]:। এটি অবস্থানগত আর্গুমেন্টগুলির সাথে কাজ করে যখন গণনা হয় না।
এম 3 এন্ড

10

এটি একটি সাধারণ পাইথন তালিকা। আপনি যে ব্যতিক্রমটির জন্য এটি ধরবেন তা হ'ল ইনডেক্সেরর, তবে পরিবর্তে দৈর্ঘ্যটি পরীক্ষা করা আপনি ভাল।

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 [1] এর মানটি আরগভিতে সংযোজন করতে পারেন এবং তারপরে আরগভি [1] আপনার ইনপুট করা স্ট্রিংটির সমান হয় না কিনা তা পরীক্ষা করতে পারেন উদাহরণ:

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

যারা আমাকে ভোট দিয়েছেন তাদের জন্য, ভুলটি ব্যাখ্যা না করার জন্য আপনাকে লজ্জা দেবেন।
হাসান আবদুল-করিম

আমার ধারণা এটি হ্যাচিশ কারণ। কেউ যদি যুক্তি হিসাবে সোমারস্ট্রিং পাস করে? কীভাবে এটি ব্যবহার করবেন যদি আপনি গ্রহণ করতে পারেন তবে 1 থেকে 5 টি আর্গুমেন্ট বলতে দিন?
pbogut

ব্যবহারকারী আর্গুমেন্ট সরবরাহ না করে এমন ক্ষেত্রে ডিফল্ট মান নির্ধারণের জন্য শীতল (তবে এখনও হ্যাকিশ)। কেবল যুক্ত করুন এবং তারপরে আরজিভি [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))
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.