एक शब्द के रूप में पायथॉन एर्गपर्स.नामस्पेस () का इलाज करने का सही तरीका क्या है?


228

अगर मैं परिणामों का उपयोग करना चाहता हूं argparse.ArgumentParser(), जो एक Namespaceवस्तु है, एक विधि के साथ जो शब्दकोश या मानचित्रण जैसी वस्तु की अपेक्षा करती है ( संग्रह देखें। मैपिंग ), तो इसे करने का सही तरीका क्या है?

C:\>python
Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)] on win
32
Type "help", "copyright", "credits" or "license" for more information.
>>> import argparse
>>> args = argparse.Namespace()
>>> args.foo = 1
>>> args.bar = [1,2,3]
>>> args.baz = 'yippee'
>>> args['baz']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'Namespace' object has no attribute '__getitem__'
>>> dir(args)
['__class__', '__contains__', '__delattr__', '__dict__', '__doc__', '__eq__', '_
_format__', '__getattribute__', '__hash__', '__init__', '__module__', '__ne__',
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__
', '__str__', '__subclasshook__', '__weakref__', '_get_args', '_get_kwargs', 'ba
r', 'baz', 'foo']

क्या किसी वस्तु का "पहुंच" और उसकी __dict__संपत्ति का उपयोग करना उचित है ?

मुझे लगता है कि जवाब नहीं है: __dict__कार्यान्वयन के लिए एक सम्मेलन की तरह बदबू आ रही है, लेकिन इंटरफ़ेस के लिए नहीं, जिस तरह __getattribute__से __setattr__या __contains__ऐसा प्रतीत होता है।

जवाबों:


385

आप vars के साथ नेमस्पेस के शब्दकोश तक पहुँच सकते हैं () :

>>> import argparse
>>> args = argparse.Namespace()
>>> args.foo = 1
>>> args.bar = [1,2,3]
>>> d = vars(args)
>>> d
{'foo': 1, 'bar': [1, 2, 3]}

आप चाहें तो सीधे शब्दकोश को संशोधित कर सकते हैं:

>>> d['baz'] = 'store me'
>>> args.baz
'store me'

हां, __dict__ विशेषता तक पहुंचना ठीक है। यह एक अच्छी तरह से परिभाषित, परीक्षणित और गारंटीकृत व्यवहार है।


1
डॉक्स कहते हैं: "दिए गए शब्दकोश को संशोधित नहीं किया जाना चाहिए: संबंधित प्रतीक तालिका पर प्रभाव अपरिभाषित हैं।" जो केवल (जो या तो है ) के व्यवहार को संदर्भित कर सकता है , लेकिन मैं वास्तव में निश्चित नहीं हूं। vars()locals()globals()

2
हम्म, मुझे लगता है कि मैं वास्तव में उपयोग करने के बीच के अंतर को नहीं समझता vars()और__dict__
जेसन एस

21
@delnan किसी ने डॉक्स के लिए एक गलत संपादन किया था और एक ओवर-ब्रॉड अडिशन बनाया था। बाद में डॉक्स को ठीक कर लिया गया। Docs.python.org/2.7/library/functions.html#vars देखें जबकि कुछ विशेष मामले हैं जिनमें केवल-केवल शब्दकोश हैं (जैसे स्थानीय और वर्ग शब्दकोश प्रॉक्सी), बाकी के मामले अपूरणीय हैं। वार्स (obj) कॉल पर्याय साथ obj .__ dict__ है। एक अर्गपर्स नामस्थान के मामले में , vars (args) एक अपूरणीय शब्दकोश के लिए सीधी पहुँच प्रदान करता है।
रेमंड हेटिंगर

1
@RaymondHettinger ठीक है, साफ-सुथरा। मुझे वह नोट /3/डॉक्स के संस्करण से मिला (निकट निरीक्षण पर, 3.1 से 3.4 सहित), इसलिए सुधार स्पष्ट रूप से वहां गायब है।

8
@delnan I ने अभी 3.3 और 3.3 डॉक्स अपडेट किए हैं। यह कल दिखाई देगा। इस पर ध्यान दिलाने के लिए धन्यवाद।
रेमंड हेटिंगर

64

सीधे घोड़े के मुंह से :

यदि आप विशेषताओं के बारे में तानाशाही जैसा विचार रखना पसंद करते हैं, तो आप मानक पायथन मुहावरे का उपयोग कर सकते हैं vars():

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
>>> args = parser.parse_args(['--foo', 'BAR'])
>>> vars(args)
{'foo': 'BAR'}

- पायथन स्टैंडर्ड लाइब्रेरी, 16.4.4.6। नामस्थान वस्तु


1
फिर भी 'फू' याद आती है '-'। उस पर कोई विचार?
user2678074

1
@ user2678074 यह शेल फ्लैग से मेल खाने के लिए जानबूझकर किया गया है। डैथ अजगर के निष्पादन के अंदर समरूप हैं।
एरिक

vars(args)मुझे देता हैTypeError: 'dict' object is not callable
user5359531

6
@ user5359531 आप शायद varsएक चर के साथ वैश्विक overwrote । आप __builtins__.varsइसे सीधे एक्सेस करने के लिए या del varsइसे छायांकित करने के लिए उपयोग कर सकते हैं ।
निक टी

@NickT माइनर करेक्शन: पायथन फंक्शन्स स्टेटिक रूप से स्कोप किए जाते हैं, यदि आप किसी फंक्शन में ग्लोबल वैरिएबल को शैडो करते हैं, तो वह आइडेंटिफायर हमेशा उस फंक्शन के भीतर या उसके बाद होने वाले फंक्शन में भी लोकल वेरिएबल को रेफर करेगा del। मॉड्यूल के दायरे में "संयुक्त राष्ट्र की छाया" बिल्डरों के लिए काम del करेगा
अगस्तुर

-1

क्या किसी वस्तु में "पहुंच" और उसके हुक्म का इस्तेमाल करना उचित है संपत्ति का ?

सामान्य तौर पर, मैं "नहीं" कहूंगा। हालाँकि, Namespaceमुझे तब से अधिक इंजीनियर के रूप में मारा गया है, जब संभवतया निर्मित प्रकारों से कक्षाएं विरासत में नहीं मिली थीं।

दूसरी ओर, Namespaceएक कार्य-उन्मुख दृष्टिकोण को प्रस्तुत करता है, और मैं ऐसी स्थिति के बारे में नहीं सोच सकता जो हड़पने के लिए कहेगी __dict__, लेकिन मेरी कल्पना की सीमाएँ आपके जैसी नहीं हैं।


11
__Dict__ विशेषता का उपयोग करना पूरी तरह से ठीक है। आत्मनिरीक्षण भाषा के लिए मौलिक है। इस विशेषता को एक कारण के लिए सार्वजनिक किया गया था :-)
रेमंड हेटिंगर 23

8
लेकिन पायथन में सब कुछ "सार्वजनिक" है। उदाहरण में उपयोग किए जाने वाले कार्यान्वयन चर और सार्वजनिक इंटरफ़ेस के बीच कोई अंतर नहीं है (अग्रणी अंडरस्कोर सम्मेलन को छोड़कर)। विशेष रूप से एक शब्दकोश जैसी वस्तु में: उदाहरण के तरीकों के बीच की रेखा, और शब्दकोश के मान जो कार्य हैं, थोड़ा धुंधला है।
जेसन एस

यदि आप नामित पैरामीटर के रूप में तर्क पारित कर रहे हैं? do_something(**args.__dict__)
ऑरेंजडॉग
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.