আরগপার্সের সাথে কমান্ড-লাইন আর্গুমেন্ট হিসাবে আমি কীভাবে একটি তালিকা পাস করতে পারি?


441

কমান্ড লাইন প্রোগ্রামের যুক্তি হিসাবে আমি একটি তালিকা পাস করার চেষ্টা করছি। সেখানে একটা Is argparseবিকল্প হিসাবে কোনো তালিকা পাস বিকল্প?

parser.add_argument('-l', '--list',
                      type=list, action='store',
                      dest='list',
                      help='<Required> Set flag',
                      required=True)

স্ক্রিপ্ট নীচের মত বলা হয়

python test.py -l "265340 268738 270774 270817"

উত্তর:


879

টি এল; ডিআর

nargsবিকল্প বা বিকল্পের 'append'সেটিংস ব্যবহার করুন action(আপনি কীভাবে ব্যবহার করতে চান ব্যবহারকারী ইন্টারফেসটি তার উপর নির্ভর করে)।

nargs

parser.add_argument('-l','--list', nargs='+', help='<Required> Set flag', required=True)
# Use like:
# python arg.py -l 1234 2345 3456 4567

nargs='+'1 বা ততোধিক আর্গুমেন্ট nargs='*'নেয়, শূন্য বা আরও বেশি লাগে।

পরিশেষে যোগ

parser.add_argument('-l','--list', action='append', help='<Required> Set flag', required=True)
# Use like:
# python arg.py -l 1234 -l 2345 -l 3456 -l 4567

সঙ্গে appendআপনি প্রদান বিকল্প একাধিক বার তালিকা বিল্ড আপ।

ব্যবহার করবেন না type=list!!! - বোধহয় কোন অবস্থা যেখানে আপনি ব্যবহার করতে চান হবে type=listসঙ্গে argparse। কখনো।


আসুন আসুন আমরা আরও কিছুটা আলাদাভাবে দেখে নিই যে কেউ এটির চেষ্টা করতে পারে এবং শেষ ফলাফল।

import argparse

parser = argparse.ArgumentParser()

# By default it will fail with multiple arguments.
parser.add_argument('--default')

# Telling the type to be a list will also fail for multiple arguments,
# but give incorrect results for a single argument.
parser.add_argument('--list-type', type=list)

# This will allow you to provide multiple arguments, but you will get
# a list of lists which is not desired.
parser.add_argument('--list-type-nargs', type=list, nargs='+')

# This is the correct way to handle accepting multiple arguments.
# '+' == 1 or more.
# '*' == 0 or more.
# '?' == 0 or 1.
# An int is an explicit number of arguments to accept.
parser.add_argument('--nargs', nargs='+')

# To make the input integers
parser.add_argument('--nargs-int-type', nargs='+', type=int)

# An alternate way to accept multiple inputs, but you must
# provide the flag once per input. Of course, you can use
# type=int here if you want.
parser.add_argument('--append-action', action='append')

# To show the results of the given option to screen.
for _, value in parser.parse_args()._get_kwargs():
    if value is not None:
        print(value)

আপনি আশা করতে পারেন আউটপুট এখানে:

$ python arg.py --default 1234 2345 3456 4567
...
arg.py: error: unrecognized arguments: 2345 3456 4567

$ python arg.py --list-type 1234 2345 3456 4567
...
arg.py: error: unrecognized arguments: 2345 3456 4567

$ # Quotes won't help here... 
$ python arg.py --list-type "1234 2345 3456 4567"
['1', '2', '3', '4', ' ', '2', '3', '4', '5', ' ', '3', '4', '5', '6', ' ', '4', '5', '6', '7']

$ python arg.py --list-type-nargs 1234 2345 3456 4567
[['1', '2', '3', '4'], ['2', '3', '4', '5'], ['3', '4', '5', '6'], ['4', '5', '6', '7']]

$ python arg.py --nargs 1234 2345 3456 4567
['1234', '2345', '3456', '4567']

$ python arg.py --nargs-int-type 1234 2345 3456 4567
[1234, 2345, 3456, 4567]

$ # Negative numbers are handled perfectly fine out of the box.
$ python arg.py --nargs-int-type -1234 2345 -3456 4567
[-1234, 2345, -3456, 4567]

$ python arg.py --append-action 1234 --append-action 2345 --append-action 3456 --append-action 4567
['1234', '2345', '3456', '4567']

টেকওয়েস :

  • ব্যবহার করুন nargsবাaction='append'
    • nargsব্যবহারকারীর দৃষ্টিকোণ থেকে আরও সহজ হতে পারে, তবে অবস্থানগত আর্গুমেন্ট থাকলে এটি অনর্থক হতে পারে কারণ অবস্থানগত যুক্তিটি argparseকী হওয়া উচিত এবং কোনটির সাথে সম্পর্কিত তা বলতে পারে না nargs; আপনার যদি অবস্থানগত যুক্তি থাকে তবে action='append'আরও ভাল পছন্দ হতে পারে।
    • যদি উপরে সত্য শুধু nargsদেওয়া হয় '*', '+'অথবা '?'। আপনি যদি একটি পূর্ণসংখ্যার নম্বর সরবরাহ করেন (যেমন 4) তবে বিকল্পগুলির সাথে nargsঅবস্থানগত আর্গুমেন্টগুলি মিশ্রিত করতে কোনও সমস্যা argparseহবে না কারণ বিকল্পটির জন্য ঠিক কতগুলি মান আশা করা উচিত তা জানতে পারবেন।
  • কমান্ড লাইন 1 এ উদ্ধৃতিগুলি ব্যবহার করবেন না
  • ব্যবহার করবেন না type=list, কারণ এটি তালিকার একটি তালিকা ফিরে আসবে
    • এটি ঘটে কারণ হুডের নীচে প্রতিটি পৃথক প্রদত্ত যুক্তি আপনাকে আপনার নির্বাচিত যুক্তিকে বাধ্য করার জন্য argparseমানটি ব্যবহার করে , সমস্ত যুক্তির সমষ্টি নয়।typetype
    • type=intইনটগুলির তালিকা পেতে (বা যা কিছু হোক) আপনি (বা যাই হোক না কেন) ব্যবহার করতে পারেন

1 : আমি সাধারণভাবে বলতে চাই না .. আমার অর্থ হল একটি তালিকা পাস করারargparse জন্য কোট ব্যবহার করা আপনি যা চান তা নয়।


3
স্ট্রিংগুলির তালিকা সম্পর্কে কী? এটি একাধিক স্ট্রিং আর্গুমেন্ট ("wassup", "কিছু" এবং "অন্য") এই তালিকাগুলির তালিকায় পরিবর্তিত হয় যা দেখতে এই জাতীয় দেখাচ্ছে: [['w', 'a', 's', 's', 'u' , 'পি'], ['এস', 'ও', 'এম', 'ই', 'টি', 'এইচ', 'আই', 'এন', 'জি'], ['ই', ' l ',' s ',' ই ']]
rd108

3
@ rd108 আমি দেখেছি, আমি বাজি ধরছি যে আপনি type=listবিকল্পটি ব্যবহার করছেন । এটি ব্যবহার করবেন না। এটি স্ট্রিংকে তালিকায় পরিণত করে এবং অতএব তালিকার তালিকাগুলি।
শেঠমোর্টন

1
@ ড্রয়ার সমস্ত ইনপুট স্ট্রিং হিসাবে ধরে নেওয়া হয় যদি না আপনি typeঅন্য কোনও বস্তুর জন্য প্যারামিটার সেট করেন । ডিফল্টরূপে এই পদ্ধতিটি স্ট্রিংগুলির একটি তালিকা প্রদান করে।
শেঠমোর্টন

1
--পজিশনাল আর্গুমেন্ট বনাম বিকল্পগুলি বিভক্ত করতে পারে। prog --opt1 par1 ... -- posp1 posp2 ...
0andriy

1
অবস্থানগত আর্গুমেন্টগুলি থাকলে এটি অনাদি হতে পারে কারণ আরগপার্স স্থিতিযুক্ত যুক্তিটি কী হওয়া উচিত এবং নার্গগুলির মধ্যে কী তা বলতে পারে না--আমার পূর্ববর্তী মন্তব্যে উদাহরণস্বরূপ এটিকে চিত্রিত করতে সহায়তা করে। --সমস্ত অবস্থানগত আর্গুমেন্ট অনুসরণ করে IW ব্যবহারকারী সরবরাহ করে।
ইন্দ্রিয়

83

আমি স্ক্রিপ্টে পরে পার্স করা একটি সীমিত স্ট্রিং পাস করা পছন্দ করি। এর কারণগুলি; তালিকাটি কোনও ধরণের intবা হতে পারে strএবং nargsএকাধিক optionচ্ছিক আর্গুমেন্ট এবং অবস্থানগত আর্গুমেন্ট উপস্থিত থাকলে আমি কখনও কখনও সমস্যার মধ্যে পড়ি।

parser = ArgumentParser()
parser.add_argument('-l', '--list', help='delimited list input', type=str)
args = parser.parse_args()
my_list = [int(item) for item in args.list.split(',')]

তারপর,

python test.py -l "265340,268738,270774,270817" [other arguments]

বা,

python test.py -l 265340,268738,270774,270817 [other arguments]

ভাল কাজ করবে। ডিলিমিটারটি একটি স্থানও হতে পারে, যা প্রশ্নের উদাহরণের মতো যুক্তির মানটির চারপাশে উদ্ধৃতি প্রয়োগ করে।


57
পোস্ট-প্রসেসিংয়ের পরিবর্তে typeআপনি যুক্তিটি সেট করতে পারেন । lambda s: [int(time) for item in s.split(',')]args.list
চিপনার

13
@ চ্যাপনার, হ্যাঁ আপনি একেবারে ঠিক আছেন এবং এটি আরও অজগর হতে পারে - কেবল একটি ছোট টাইপো: int(time)হওয়া উচিত int(item)। আমার উদাহরণটি আমি সাধারণত যা করি তার একটি সরলীকৃত সংস্করণ ছিল, যেখানে আমি সাধারণ প্রক্রিয়াজাতকরণের পরিবর্তে আরও অনেক কিছুই পরীক্ষা করি। তবে
সোজা

1
এই উত্তরটি সর্বাধিক পাইথোনিক বলে মনে হচ্ছে
কোয়েটজলক্যাটল

1
@ শেপনার মন্তব্যটি মারাত্মক নিনজা
দক্ষতা

1
lambda items: list(csv.reader([items]))[0]মান CSV লাইব্রেরি থেকে মন্তব্যকারীকে একটি পরিবর্তিত সংস্করণ @chepner (: সুত্র কেউ নির্বিচারে CSV ইনপুট সম্পর্কে চিন্তিত জন্য উত্তর থেকে @adamk )।
কেভিন

19

অতিরিক্ত হিসাবে nargs, আপনি choicesযদি আগে থেকে তালিকাটি জানেন তবে আপনি ব্যবহার করতে পারেন:

>>> parser = argparse.ArgumentParser(prog='game.py')
>>> parser.add_argument('move', choices=['rock', 'paper', 'scissors'])
>>> parser.parse_args(['rock'])
Namespace(move='rock')
>>> parser.parse_args(['fire'])
usage: game.py [-h] {rock,paper,scissors}
game.py: error: argument move: invalid choice: 'fire' (choose from 'rock',
'paper', 'scissors')

10

আরগপার্সের অ্যাড_গারগমেন্ট পদ্ধতিতে নার্গেস প্যারামিটার ব্যবহার করা

আমি একটি অ্যাড_গারগমেন্ট প্যারামিটার হিসাবে নার্গেস = ' ' ব্যবহার করি আমি কোনও স্পষ্ট যুক্তি পাস না করে থাকলে ডিফল্ট বাছাই করতে অপশনটিতে আমি বিশেষত নার্জ = ' ' ব্যবহার করেছি

উদাহরণস্বরূপ একটি কোড স্নিপেট সহ:

উদাহরণ: temp_args1.py

দয়া করে নোট করুন: নীচের নমুনা কোডটি পাইথন 3 তে লেখা আছে। মুদ্রণ বিবৃতি ফর্ম্যাট পরিবর্তন করে পাইথন 2 এ চালানো যেতে পারে

#!/usr/local/bin/python3.6

from argparse import ArgumentParser

description = 'testing for passing multiple arguments and to get list of args'
parser = ArgumentParser(description=description)
parser.add_argument('-i', '--item', action='store', dest='alist',
                    type=str, nargs='*', default=['item1', 'item2', 'item3'],
                    help="Examples: -i item1 item2, -i item3")
opts = parser.parse_args()

print("List of items: {}".format(opts.alist))

দ্রষ্টব্য: আমি একাধিক স্ট্রিং আর্গুমেন্ট সংগ্রহ করছি যা তালিকায় সঞ্চিত হয় - opts.alist আপনি যদি পূর্ণসংখ্যার তালিকা চান তবে পার্সার এড প্যারামিটারটি পরিবর্তন করুন।

কার্যকর করার ফলাফল:

python3.6 temp_agrs1.py -i item5 item6 item7
List of items: ['item5', 'item6', 'item7']

python3.6 temp_agrs1.py -i item10
List of items: ['item10']

python3.6 temp_agrs1.py
List of items: ['item1', 'item2', 'item3']

1
@ পাই_মিনিয়ন একটি যুক্তি হিসাবে একটি তালিকা ব্যবহার করার উপায় আছে, এবং পাশাপাশি তালিকা হিসাবে আউটপুট আছে? temp_args1.py -i [item5 ,item6, item7]এবং আউটপুটটিও তালিকা হিসাবে প্রকাশিত হবে (নেস্টেড তালিকার পরিবর্তে)
মুন্দ্রা

@ মুন্ড্রা হ্যাঁ আপনি জিজ্ঞাসা খুশি। `` ars parser.add_argument ('- o', '--options', ক্রিয়া = 'স্টোর', গন্তব্য = 'অপট_লিস্ট', টাইপ = str, নার্গস = '*', ডিফল্ট = নমুনা তালিকা, সহায়তা = "ডাটাবেসের স্ট্রিং সাদা স্থান দ্বারা পৃথকীকৃত উদাহরণ। উদাঃ নমুনা_লিস্ট = [অপশন 4, অপশন 5]
পাই_মিনিয়ন

1
@ পাই_মিনিয়ন আপনাকে ধন্যবাদ আজ পরে এটি পরীক্ষা করতে যাচ্ছি।
মুন্দ্রা

আমি এটি ব্যবহার করেছি, এটি আর্গুমেন্ট থেকে তালিকা তৈরির জন্য খুব দরকারী।
siby

5

আপনি যদি একটি একক স্যুইচ একাধিক পরামিতি নিতে চান, তবে আপনি ব্যবহার করুন nargs='+'। যদি আপনার উদাহরণ '-l' আসলে পূর্ণসংখ্যা গ্রহণ করে:

a = argparse.ArgumentParser()
a.add_argument(
    '-l', '--list',  # either of this switches
    nargs='+',       # one or more parameters to this switch
    type=int,        # /parameters/ are ints
    dest='list',     # store in 'list'.
    default=[],      # since we're not specifying required.
)

print a.parse_args("-l 123 234 345 456".split(' '))
print a.parse_args("-l 123 -l=234 -l345 --list 456".split(' '))

উত্পাদন

Namespace(list=[123, 234, 345, 456])
Namespace(list=[456])  # Attention!

যদি আপনি একই যুক্তিটিকে একাধিকবার নির্দিষ্ট করে থাকেন তবে ডিফল্ট ক্রিয়া ( 'store') বিদ্যমান ডেটার বদলে।

বিকল্পটি হল appendক্রিয়াটি ব্যবহার করা :

a = argparse.ArgumentParser()
a.add_argument(
    '-l', '--list',  # either of this switches
    type=int,        # /parameters/ are ints
    dest='list',     # store in 'list'.
    default=[],      # since we're not specifying required.
    action='append', # add to the list instead of replacing it
)

print a.parse_args("-l 123 -l=234 -l345 --list 456".split(' '))

যা উত্পাদন করে

Namespace(list=[123, 234, 345, 456])

অথবা কমা-বিচ্ছিন্ন মানগুলি পার্স করার জন্য আপনি একটি কাস্টম হ্যান্ডলার / ক্রিয়া লিখতে পারেন যাতে আপনি এটি করতে পারেন

-l 123,234,345 -l 456

5

ইন add_argument(), typeকেবলমাত্র একটি কলযোগ্য অবজেক্ট যা স্ট্রিং গ্রহণ করে এবং বিকল্পটির মান দেয়।

import ast

def arg_as_list(s):                                                            
    v = ast.literal_eval(s)                                                    
    if type(v) is not list:                                                    
        raise argparse.ArgumentTypeError("Argument \"%s\" is not a list" % (s))
    return v                                                                   


def foo():
    parser.add_argument("--list", type=arg_as_list, default=[],
                        help="List of values")

এটি এর অনুমতি দেবে:

$ ./tool --list "[1,2,3,4]"

মনে রাখবেন যে যদি স্ট্রিংগুলি পাস করার প্রয়োজন হয় তবে এই পদ্ধতির জন্য তাদের কমান্ড লাইনে যথাযথভাবে উদ্ধৃতি দিতে হবে। একজন ব্যবহারকারী এটি অপ্রত্যাশিত খুঁজে পেতে পারেন। যদি কেবল পূর্ণসংখ্যাগুলি পার্স করা হয় তবে এটি ঠিক।
শেঠমোর্টন

1

যদি আপনার কোনও নেস্টেড তালিকা থাকে যেখানে অভ্যন্তরীণ তালিকাগুলিতে বিভিন্ন ধরণের এবং দৈর্ঘ্য থাকে এবং আপনি টাইপটি সংরক্ষণ করতে চান, যেমন,

[[1, 2], ["foo", "bar"], [3.14, "baz", 20]]

তাহলে আপনি নীচে প্রদর্শিত এই প্রশ্নটির জন্য @ সাম-ম্যাসন দ্বারা প্রস্তাবিত সমাধানটি ব্যবহার করতে পারেন :

from argparse import ArgumentParser
import json

parser = ArgumentParser()
parser.add_argument('-l', type=json.loads)
parser.parse_args(['-l', '[[1,2],["foo","bar"],[3.14,"baz",20]]'])

যা দেয়:

Namespace(l=[[1, 2], ['foo', 'bar'], [3.14, 'baz', 20]])

0

আমি একাধিক তালিকা, পূর্ণসংখ্যার মান এবং স্ট্রিংগুলি হ্যান্ডেল করতে চাই।

সহায়ক লিঙ্ক => পাইথনে বাশ ভেরিয়েবল কীভাবে পাস করবেন?

def main(args):
    my_args = []
    for arg in args:
        if arg.startswith("[") and arg.endswith("]"):
            arg = arg.replace("[", "").replace("]", "")
            my_args.append(arg.split(","))
        else:
            my_args.append(arg)

    print(my_args)


if __name__ == "__main__":
    import sys
    main(sys.argv[1:])

অর্ডার গুরুত্বপূর্ণ নয়। আপনি একটি তালিকা পাস করতে চান, শুধু মাঝে হিসেবে "["এবং "]একটি কমা ব্যবহার করে সেগুলি পৃথক।

তারপর,

python test.py my_string 3 "[1,2]" "[3,4,5]"

আউটপুট => ['my_string', '3', ['1', '2'], ['3', '4', '5']], my_argsভেরিয়েবলের মধ্যে সুসংগতভাবে যুক্তি রয়েছে।


0

আমি মনে করি সবচেয়ে মার্জিত সমাধান হ'ল ল্যাম্বডা ফাংশনটিকে "টাইপ করুন" তে প্রেরণ করা, চ্যাপনার দ্বারা উল্লিখিত হিসাবে। এগুলি ছাড়াও, যদি আপনার তালিকার সীমানাটি কী হবে তা আপনি যদি আগেই জানেন না, তবে আপনি পুনরায় স্প্লিট করতে একাধিক ডিলিমিটারগুলিও পাস করতে পারবেন:

# python3 test.py -l "abc xyz, 123"

import re
import argparse

parser = argparse.ArgumentParser(description='Process a list.')
parser.add_argument('-l', '--list',
                    type=lambda s: re.split(' |, ', s),
                    required=True,
                    help='comma or space delimited list of characters')

args = parser.parse_args()
print(args.list)


# Output: ['abc', 'xyz', '123']

আপনি -lউদাহরণ কল বলতে কি বোঝাতে চেয়েছিলেন ? কোথা -nথেকে এল ?
অ্যান্টনি

এছাড়াও পাইথন ৩.৮.২-তে আমার জন্য সমাধানটি কাজ করে না। এখানে কোড হল: parser.add_argument('-l', '--list', type = lambda s: re.split('[ ,;]', s))। এখানে ইনপুট হল: script.py -l abc xyz, abc\nxyz। অবশেষে, এখানে ফলাফল:script.py: error: unrecognized arguments: xyz, abcnxyz
এন্থনি

আমার উদাহরণটি পরিবর্তন করুন যাতে এটি কার্যকর হয় :)
নীবুলাস্টিক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.