2010-02-03 12 views
11

मैं ConfigParser उपयोग कर रहा हूँ एक विन्यास फ़ाइल से डेटा में लोड करने के लिए इस प्रकार है:Python ConfigParser .items() से DEFAULT को बहिष्कृत कैसे करें?

test.conf:

[myfiles] 
fileone: %(datadir)s/somefile.foo 
filetwo: %(datadir)s/nudderfile.foo 

load.py:

import ConfigParser 

config = ConfigParser.ConfigParser({'datadir': '/tmp'}) 
config.read('test.conf') 

print config.items('myfiles') 
print config.get('myfiles', 'datadir') 

आउटपुट :

$ python load.py 
[('datadir', '/tmp'), ('filetwo', '/tmp/nudderfile.foo'), ('fileone', '/tmp/somefile.foo')] 
/tmp 

मुझे आश्चर्य है कि परिवर्तनीय प्रतिस्थापन ('datadir', '/tmp') के लिए डिफ़ॉल्ट रूप से दिखाए जा रहे हैं। items() और .get() रिटर्न, जैसे कि वे कॉन्फ़िगरेशन फ़ाइल में मान थे। क्या यह व्यवहार अपेक्षित है? कोई काम आसपास है, ताकि मैं बस .items() को फिर से डिफ़ॉल्ट शब्दकोश मान प्राप्त किए बिना फिर से सक्रिय कर सकूं, लेकिन अभी भी जादू इंटरपोलेशन का उपयोग कर रहा हूं?

संदर्भ: http://docs.python.org/library/configparser.html

धन्यवाद!

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

foo: bar 
zap: %(foo)snowl 

मैं [... ('zap': 'barnowl')]

मिलेगा यह सुंदर साफ है, लेकिन मैं अभी भी कर रहा हूँ यह सोचकर कि मैं जो हासिल करना चाहता हूं उसे पूरा कर सकता हूं: डिफ़ॉल्ट रूप से बिना चर के इंटरपोलेशन के साथ, मेरी कॉन्फ़िगरेशन फ़ाइलों में नाम/मूल्य जोड़े पर पुन: प्रयास करें।

मेरा विशिष्ट परिदृश्य यह है: मैं कॉन्फ़िगरेशन ऑब्जेक्ट को {basedir: '/foo/bar'} जैसे कुछ प्रारंभ करना चाहता था, क्योंकि कुछ फ़ाइलों के पूर्ण पथ स्थापना द्वारा भिन्न होते हैं। फिर मुझे उस कॉन्फ़िगरेशन ऑब्जेक्ट को पास करने की आवश्यकता है और फ़ाइलों के माध्यम से कई अन्य वर्गों को फिर से चालू करना होगा। मैं नहीं चाहता कि प्रत्येक वर्ग जो विन्यास को पढ़ता है उसे यह जानना होगा कि इसे कुछ डिफ़ॉल्ट के साथ शुरू किया गया था और इसे अनदेखा करना चाहिए, क्योंकि वे वास्तविक फाइल नहीं हैं। क्या यह संभव है? .item() और .get() से डिफ़ॉल्ट छिपाने का कोई तरीका है लेकिन अभी भी इंटरपोलेशन है? धन्यवाद!

config = ConfigParser.ConfigParser({'blahblahblah': 'blah'}) 
config.read('test.conf') 

blahblahblah कुंजी भी items में दिखाई देगा, क्योंकि यह .ini फ़ाइल में एक टेम्पलेट है, लेकिन आप एक डिफ़ॉल्ट के रूप में निर्दिष्ट है क्योंकि:

+2

मैं नहीं जान सकता क्यों इस डिफ़ॉल्ट व्यवहार है, अकेले क्यों कोई रास्ता नहीं इसे बंद करने के लिए है। स्पष्टीकरण के लिए –

उत्तर

1

इस प्रयास करें। इस प्रकार ConfigParser डिफ़ॉल्ट का व्यवहार करता है: यदि यह उन्हें फ़ाइल में नहीं ढूंढ पाता है, तो यह उनके डिफ़ॉल्ट मान निर्दिष्ट करता है।

तो ऐसा लगता है कि आपको अवधारणाओं का सरल भ्रम है।

+0

धन्यवाद। इसलिए डिफ़ॉल्ट कुंजी को कुछ कुंजी के लिए डिफ़ॉल्ट मान प्रदान करने के लिए * और * कॉन्फ़िगरेशन फ़ाइल में एम्बेडेड चर के "जादू इंटरपोलेशन" के लिए उपयोग किया जाता है। साथ ही, विन्यास फाइल में परिभाषित चर भी "जादू प्रक्षेप" के लिए उपयोग किया जाता है, इसलिए यदि मैं परिभाषित: foo: बार जैप:% (foo) snowl मैं [मिल जाएगा ... ('जैप ':' barnowl ')] यह बहुत साफ है, लेकिन मैं अभी भी सोच रहा हूं कि मैं जो हासिल करना चाहता हूं उसे पूरा कर सकता हूं: मेरे कॉन्फ़िगरेशन फ़ाइलों में नाम/मूल्य जोड़े पर, फिर से डिफ़ॉल्ट के इंटरपोलेशन के साथ, डिफ़ॉल्ट के बिना। – user264902

4

आम तौर पर, मुझे configparser.Configparser कक्षा बहुत उपयोगी है, लेकिन इसकी कमी भी है। Others have, too

class ConfigParser(configparser.ConfigParser): 
    """Can get options() without defaults 
    """ 
    def options(self, section, no_defaults=False, **kwargs): 
     if no_defaults: 
      try: 
       return list(self._sections[section].keys()) 
      except KeyError: 
       raise NoSectionError(section) 
     else: 
      return super().options(section, **kwargs) 

:

हालांकि, यह subclassed और बढ़ाया जा सकता है, कभी कभी अच्छी तरह से, कभी कभी नहीं इतनी अच्छी तरह से (= बहुत कार्यान्वयन निर्भर)

यहाँ अपनी समस्या के लिए एक समाधान, python3 में परीक्षण किया गया है यह खराब उदाहरणों में से एक है, क्योंकि यह आंशिक रूप से the source codeoptions() की प्रतिलिपि बना रहा है। यह कॉन्फ़िगरर बेस क्लास RawConfigParser विकल्प _options(self, section) का आंतरिक गेटर प्रदान करेगा जो अपवाद कास्ट, और options() शामिल करेगा जो इसका उपयोग करेगा। फिर, उपclassing में हम _options() का पुन: उपयोग कर सकते हैं।

पायथन 2 के लिए, मेरा मानना ​​है कि केवल परिवर्तन super()super(ConfigParser,self) पर कॉल करें।

फिर आप उपयोग कर सकते हैं:

print config.options('myfiles', no_defaults=True) 

और भी तेज़ी से दोहराने में उस सूची का उपयोग करें।

+0

आप सही रास्ते पर हैं, हालांकि उन्होंने .items(), नहीं। विकल्प() के बारे में पूछा। मुझे लगता है कि यह उसे वहां ले जाएगा हालांकि। –

+0

मैं अपने प्रश्न को समझता हूं कि "मेरी कॉन्फ़िगरेशन फ़ाइलों में नाम/मूल्य जोड़े पर पुनरावृत्ति कैसे करें, चर के बिना चर के इंटरपोलेशन के साथ।" और यही उपरोक्त कोड करता है। मेरे लिए यह एक सही जवाब है। दुर्भाग्य से, अक्सर मामला है, सवाल का पोस्टर सक्रिय प्रतीत नहीं होता है। अन्यथा हम उसे निर्णय ले सकते हैं कि क्या यह उत्तर के लिए स्वीकार्य है या नहीं। – cfi

+0

हाँ, सवाल चल रहा है और फोकस की जरूरत है। वह कोड में .items का उपयोग करता है, और अंतिम वाक्य में। वह नाम/वैल जोड़े के लिए पूछता है, जो कि .items करता है। विकल्प सिर्फ चाबियाँ देता है। आपके जवाब ने मुझे ओवरराइड करने में मदद की। हालांकि धन्यवाद। –

2

क्या आप केवल डिफ़ॉल्ट को फ़िल्टर नहीं कर सकते?

उदा .:

filtered_items = [x for x in config.items('myfiles') if x[0] not in config.defaults()]

संबंधित मुद्दे