আরগপার্স: 'এক্স' উপস্থিত থাকলে প্রয়োজনীয় আর্গুমেন্ট '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সেট করা নেই। যদি তা না হয় তবে কেন তর্ক lportও rportযুক্তি দিবেন না 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.