एक callee.py के पास यह Namespace है, जो इसके argparse का उपयोग करता है:

parser = Namespace(action='run', action_area='park', severity='high')

In [30]: parser.action
Out[30]: 'run'

यदि आप कमांड लाइन में टाइप करते हैं, तो यह पर्याप्त होना चाहिए:

callee.py --run --action_area gym --severity low

अगर कॉल किसी अन्य प्रोग्राम caller.py के अंदर है, तो मैं यह करना चाहता हूं:

callee.py sth.run sth.action_area 'gym' sth.severity 'low'

फायदे हैं: अधिक विनियमित अगर callee.py में args बदलता है तो अपडेट करना आसान हो जाता है

काश sth argparse से आए या कुछ ऐसा जो मुझे खुद को कोड करने की आवश्यकता न हो।

मैं इस तरह sth बना सकता हूं:

class ParserKeys(object):
    def __init__(self, keys):
        self.keys = keys
        for key in keys:
            setattr(self, key, '--{0}'.format(key))

sth = ParserKeys(vars(parser).keys())

In [91]: sth.action
Out[91]: '--action'

मेरा सवाल है: क्या argparse के अंदर कोई रास्ता है या अन्य तरीकों से मुझे इसके लिए कक्षा बनाने की ज़रूरत नहीं है?

आवश्यकताओं की व्याख्या करने के लिए यह केवल एक उदाहरण है, इसे कैसे प्राप्त किया जाए argparse तक सीमित नहीं है यदि सुविधा उपलब्ध नहीं है (मुझे लगता है कि यह होना चाहिए)।

मुझे यकीन है कि मैं इस सुविधा की आवश्यकता वाला पहला और आखिरी व्यक्ति नहीं हूं। मुझे उम्मीद है कि इस बार मैं इसे स्पष्ट रूप से समझाऊंगा।

-1
Gang 26 जुलाई 2017, 02:02
1
अरे, argparse का उपयोग करने का यह सामान्य तरीका नहीं है ...
 – 
wim
26 जुलाई 2017, 02:03
1
"नाम प्राप्त करें जो मुख्य क्रिया है" से आपका क्या मतलब है?
 – 
user2357112 supports Monica
26 जुलाई 2017, 02:04
1
और आप कैसे जानते हैं कि यह वह स्ट्रिंग है action जिसका आप अनुसरण कर रहे हैं?
 – 
Antti Haapala
26 जुलाई 2017, 02:19
1
चूँकि argparse.Namespace एक वर्ग है, शायद आप अपना विशेष संस्करण प्राप्त कर सकते हैं जो आपको वह करने की अनुमति देगा जो आप चाहते हैं।
 – 
martineau
26 जुलाई 2017, 04:42
1
@martineau, Namespace2(argparse.Namespace) parser.x के साथ --x जोड़ा गया है? यह काम हो सकता है!
 – 
Gang
26 जुलाई 2017, 04:47

1 उत्तर

सबसे बढ़िया उत्तर

argparse का उपयोग करने का सामान्य तरीका एक पार्सर को परिभाषित करना, उसके 'तर्कों' को पॉप्युलेट करना और कमांड लाइन को पार्स करने के लिए parse_args() पर कॉल करना है।

parse_args() एक नेमस्पेस ऑब्जेक्ट देता है जिसका आप तब उपयोग करते हैं।

नेमस्पेस ऑब्जेक्ट को सीधे परिभाषित करना संभव है:

In [203]: ns = argparse.Namespace(x=12, y='abc')
In [204]: ns
Out[204]: Namespace(x=12, y='abc')
In [205]: ns.x
Out[205]: 12
In [207]: ns.z = [1,2,3]
In [208]: ns
Out[208]: Namespace(x=12, y='abc', z=[1, 2, 3])

आप मौजूदा ऑब्जेक्ट में मान जोड़ सकते हैं, लेकिन आप उन मानों तक नहीं पहुंच सकते जो परिभाषित नहीं हैं। Namespace वर्ग सरल है, मूल्यों के प्रदर्शन को सुंदर बनाने के लिए बस कुछ विधियों को जोड़ना।

आप इससे एक शब्दकोश भी प्राप्त कर सकते हैं:

In [209]: vars(ns)
Out[209]: {'x': 12, 'y': 'abc', 'z': [1, 2, 3]}

In [210]: list(vars(ns).keys())
Out[210]: ['z', 'y', 'x']

key स्ट्रिंग का उपयोग करके मान प्राप्त करना:

In [212]: getattr(ns,'x')
Out[212]: 12

आप नाम से विशेषताएँ भी सेट कर सकते हैं

In [220]: setattr(ns,'w','other')
In [221]: ns
Out[221]: Namespace(w='other', x=12, y='abc', z=[1, 2, 3])

ns अपने मूल्यों को प्रदर्शित करने के लिए जिस विधि का उपयोग करता है वह है:

def __repr__(self):
    type_name = type(self).__name__
    arg_strings = []
    for arg in self._get_args():
        arg_strings.append(repr(arg))
    for name, value in self._get_kwargs():
        arg_strings.append('%s=%r' % (name, value))
    return '%s(%s)' % (type_name, ', '.join(arg_strings))

def _get_kwargs(self):
    return sorted(self.__dict__.items())

self.__dict__ वही चीज है जो vars(ns) देता है। विशेषताओं को इस शब्दकोश में संग्रहीत किया जाता है (जैसा कि अधिकांश वस्तुओं के लिए सच है, विशेष रूप से उपयोगकर्ता परिभाषित वाले)।

यदि आप Namespace के साथ और अधिक करना चाहते हैं, या अपनी खुद की कक्षा परिभाषित करना चाहते हैं, तो मेरा सुझाव है कि argparse.py फ़ाइल में कक्षा को देखें। argparse इस वर्ग की प्रकृति के बारे में कम से कम अनुमान लगाने की कोशिश करता है। जहां संभव हो यह getattr और setattr फ़ंक्शन का उपयोग करता है। और hasattr भी:

In [222]: hasattr(ns, 'foo')
Out[222]: False
In [223]: hasattr(ns, 'w')
Out[223]: True

आपके संपादन से ऐसा लगता है कि आप नेमस्पेस में विशेषता नामों से विकल्प ध्वज को 'पुनर्प्राप्त' करना चाहते हैं। अर्थात्

 parser.add_argument('--foo', '-f', ...)
 parser.add_argument('bar', ...)
 parser.add_argument('--other', dest='baz',...)

एक Namespace(foo=..., bar=....) का उत्पादन करेगा

विशेषता नाम को dest कहा जाता है। वह तब होता है जब पार्सर द्वारा उपयोग किए जाने वाले मूल्यों को सहेजा जाता है

 setattr(namespace, dest, value)

एक स्थितीय तर्क के लिए dest उपरोक्त उदाहरण में पहला पैरामीटर, 'बार' है। एक वैकल्पिक तर्क के लिए, dest पहले लंबे पैरामीटर, ऊपर दिए गए '--foo' से लिया गया है। या इसे एक स्पष्ट dest='baz' पैरामीटर के साथ सेट किया जा सकता है।

तो बस -- को ns.__dict__ कुंजी में जोड़ना एक शुरुआत है।

argparse में ऐसा कोई कोड नहीं है जो पार्सिंग परिणामों से कमांडलाइन को फिर से बना सके।

7
hpaulj 16 मई 2018, 06:56
इसलिए argparse को बदले बिना कुंजी का नाम प्राप्त करने का कोई आसान तरीका नहीं है, लेकिन vars(parser).keys() where ParserKeys.x `x' का उपयोग करके एक वर्ग ParserKeys गतिशील बनाना संभव है?
 – 
Gang
26 जुलाई 2017, 03:15
मुझे समझ में नहीं आता कि 'कुंजी के नाम' से आपका क्या मतलब है। ns में विशेषताएँ हैं, जिनके मान पार्सर द्वारा निर्धारित किए गए हैं। मैंने दिखाया कि उन विशेषताओं के नाम कैसे प्राप्त करें, और मूल्यों को प्राप्त करने के लिए उनका उपयोग कैसे करें। मैं दोहराता हूँ, यह एक SIMPLE वर्ग वस्तु है। कुछ भी आकर्षक नहीं।
 – 
hpaulj
26 जुलाई 2017, 03:39
आपके संपादन अभी भी भ्रमित कर रहे हैं, लेकिन मुझे लगता है कि आप नेमस्पेस में मानों से कमांड लाइन को फिर से बनाने का प्रयास कर रहे हैं। यानी, Namespace(foo='one', bar=2) को ['--foo', 'one', '--bar', '2'] सूची में मैप करें।
 – 
hpaulj
26 जुलाई 2017, 07:18