আরগপার্স: 'এক্স' উপস্থিত থাকলে প্রয়োজনীয় আর্গুমেন্ট 'y'


118

নিম্নলিখিত হিসাবে আমার একটি প্রয়োজন আছে:

./xyifier --prox --lport lport --rport rport

আর্গুমেন্ট প্রক্সের জন্য, আমি উপস্থিত রয়েছে কিনা তা যাচাই করতে আমি ক্রিয়া = 'store_true' ব্যবহার করি। আমার কোনও যুক্তি লাগবে না। তবে, যদি --প্রক্স সেট করা থাকে তবে আমার পাশাপাশি rport এবং lportও প্রয়োজন । কাস্টমস কন্ডিশনাল কোডিং না লিখে আরগপার্সের সাথে এটি করার সহজ উপায় কি আছে?

আরও কোড:

non_int.add_argument('--prox', action='store_true', help='Flag to turn on proxy')
non_int.add_argument('--lport', type=int, help='Listen Port.')
non_int.add_argument('--rport', type=int, help='Proxy port.')

প্লাগিং, তবে আমি আমার লাইব্রেরি জোফ্রে উল্লেখ করতে চেয়েছিলাম । এই প্রশ্নটি যা চায় তা করতে আপনাকে উদাহরণ দেয়, উদাহরণস্বরূপ, আপনাকে নিজেরাই সবকিছু যাচাই করে না দেওয়া (স্বীকৃত উত্তরের মতো) বা লুপফোলি হ্যাকের উপর নির্ভর করা (দ্বিতীয় সর্বোচ্চ ভোটের প্রতিক্রিয়া হিসাবে)।
এমআই রাইট

: যে কেউ এখানে আসার আরেকটি আশ্চর্যজনক সমাধান জন্য stackoverflow.com/a/44210638/6045800
Tomerikoo

উত্তর:


120

না, পারস্পরিক অন্তর্ভুক্ত বিকল্পগুলির সেট তৈরি করতে আরগপারসে কোনও বিকল্প নেই ।

এটির সাথে মোকাবিলা করার সহজ উপায় হ'ল:

if args.prox and (args.lport is None or args.rport is None):
    parser.error("--prox requires --lport and --rport.")

2
আমি যা করে শেষ করেছি তা হল
আসুধক

20
parser.errorপদ্ধতির জন্য আপনাকে ধন্যবাদ , আমি এটিই খুঁজছিলাম!
মারসফট

7
আপনার 'বা' ব্যবহার করা উচিত নয়? সর্বোপরি আপনার উভয় if args.prox and (args.lport is None or args.rport is None):
অর্গগুলি দরকার

1
পরিবর্তে args.lport is None, আপনি কেবল ব্যবহার করতে পারেন not args.lport। আমার মনে হয় এটি একটু বেশি অজগর।
সিজিএফএক্স

7
এটি আপনাকে সেট করতে --lportবা --rportকরা থেকে বিরত করবে 0, যা প্রোগ্রামে একটি বৈধ ইনপুট হতে পারে।
বর্নটাইপিং

53

আপনি শর্তাধীন প্রয়োজনীয় যুক্তি থাকার কথা বলছেন। @ বার্নটাইপিংয়ের মতো বলেছিল যে আপনি ত্রুটিটি পরীক্ষা করতে পারেন এবং করতে পারেন parser.error(), বা আপনি --proxযখন নতুন যুক্তি যুক্ত করেন তখন আপনি কেবলমাত্র প্রয়োজনীয় প্রয়োগ করতে পারেন।

আপনার উদাহরণের জন্য একটি সহজ সমাধান হতে পারে:

non_int.add_argument('--prox', action='store_true', help='Flag to turn on proxy')
non_int.add_argument('--lport', required='--prox' in sys.argv, type=int)
non_int.add_argument('--rport', required='--prox' in sys.argv, type=int)

এইভাবে requiredহয় হয় Trueবা Falseব্যবহারকারী হিসাবে ব্যবহৃত হিসাবে নির্ভর করে --prox। এটিও এর নিশ্চয়তা দেয় -lportএবং -rportএকে অপরের মধ্যে স্বতন্ত্র আচরণ করতে পারে have


8
দ্রষ্টব্য যে এই ArgumentParserতালিকা ব্যতীত অন্য কোনও তালিকা থেকে যুক্তি বিশ্লেষণ করতে ব্যবহৃত হতে পারে sys.argvthis
বলপয়েন্টবেন

এছাড়াও --prox=<value>সিনট্যাক্স ব্যবহার করা গেলে এটি ব্যর্থ হবে ।
fnkr

11

কিভাবে ব্যবহার সম্পর্কে parser.parse_known_args()পদ্ধতি এবং তারপর যোগ --lportএবং --rportপ্রয়োজনীয় args যেমন args যদি --proxউপস্থিত।

# just add --prox arg now
non_int = argparse.ArgumentParser(description="stackoverflow question", 
                                  usage="%(prog)s [-h] [--prox --lport port --rport port]")
non_int.add_argument('--prox', action='store_true', 
                     help='Flag to turn on proxy, requires additional args lport and rport')
opts, rem_args = non_int.parse_known_args()
if opts.prox:
    non_int.add_argument('--lport', required=True, type=int, help='Listen Port.')
    non_int.add_argument('--rport', required=True, type=int, help='Proxy port.')
    # use options and namespace from first parsing
    non_int.parse_args(rem_args, namespace = opts)

এ ছাড়াও মনে রাখবেন যে optsদ্বিতীয় যুক্তিটি দ্বিতীয়বার পার্স করার সময় আপনি প্রথম পার্সিংয়ের পরে উত্পন্ন নেমস্পেস সরবরাহ করতে পারেন । এইভাবে, শেষ পর্যন্ত, সমস্ত বিশ্লেষণ শেষ হওয়ার পরে, আপনার সমস্ত বিকল্পের সাথে একটি একক নেমস্পেস থাকবে।

অপূর্ণতা:

  • যদি --proxউপস্থিত না হয় তবে অন্যান্য দুটি নির্ভরযোগ্য বিকল্পগুলি নামস্থানে উপস্থিত হয় না। যদিও আপনার ব্যবহারের ভিত্তিতে, যদি --proxউপস্থিত না থাকে তবে অন্যান্য বিকল্পগুলির ক্ষেত্রে যা ঘটে তা অপ্রাসঙ্গিক।
  • পার্সার সম্পূর্ণ কাঠামো জানেন না বলে ব্যবহারের বার্তাটি পরিবর্তন করতে হবে
  • --lportএবং --rportসহায়তা বার্তায় প্রদর্শিত হবে না

5

আপনি ব্যবহার করেন lportযখন proxসেট করা নেই। যদি তা না হয় তবে কেন তর্ক lportrportযুক্তি দিবেন না prox? যেমন

parser.add_argument('--prox', nargs=2, type=int, help='Prox: listen and proxy ports')

এটি আপনার ব্যবহারকারীদের টাইপিং সংরক্ষণ করে। এটি যেমন পরীক্ষা if args.prox is not None:করা ঠিক তত সহজ if args.prox:


1
উদাহরণের সম্পূর্ণতার জন্য, যখন আপনার নার্গগুলি> 1 হয়, আপনি পার্সড আর্গুমেন্ট ইত্যাদির একটি তালিকা পাবেন, যা আপনি সাধারণ বিনয়ের সাথে সম্বোধন করতে পারেন। যেমন, a,b = args.prox, a = args.prox[0], ইত্যাদি
Dannid

1

গৃহীত উত্তরটি আমার পক্ষে দুর্দান্ত কাজ করেছে! যেহেতু এখানে সমস্ত কোড টেস্ট ছাড়াই নষ্ট হয়ে গেছে আমি গৃহীত উত্তরটি কীভাবে পরীক্ষা করেছি। পরিবর্তে প্রক্রিয়াটি প্রস্থান করে parser.error()একটি argparse.ArgumentErrorত্রুটি বাড়ায় না । আপনি পরীক্ষা করতে হবে SystemExit

পাইস্টের সাথে

import pytest
from . import parse_arguments  # code that rasises parse.error()


def test_args_parsed_raises_error():
    with pytest.raises(SystemExit):
        parse_arguments(["argument that raises error"])

ইউনিটসেটস সহ

from unittest import TestCase
from . import parse_arguments  # code that rasises parse.error()

class TestArgs(TestCase):

    def test_args_parsed_raises_error():
        with self.assertRaises(SystemExit) as cm:
            parse_arguments(["argument that raises error"])

এর দ্বারা অনুপ্রাণিত: আরগপার্স পরীক্ষার জন্য ইউনিটেস্ট ব্যবহার করে - প্রস্থান ত্রুটি

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