python - ConfigParser में सूचीबद्ध है
(7)
इस पार्टी के लिए देर से आ रहा है, लेकिन मैंने हाल ही में एक सूची के लिए एक कॉन्फ़िगरेशन फ़ाइल में समर्पित अनुभाग के साथ इसे कार्यान्वित किया है:
[paths]
path1 = /some/path/
path2 = /another/path/
...
और पथ आइटम्स की एक पुनरावर्तनीय सूची प्राप्त करने के लिए config.items( "paths" )
का उपयोग करके, जैसे:
path_items = config.items( "paths" )
for key, path in path_items:
#do something with path
उम्मीद है कि यह अन्य लोगों को इस प्रश्न को गुगल करने में मदद करता है;)
ठेठ ConfigParser जेनरेट की गई फ़ाइल इस तरह दिखती है:
[Section]
bar=foo
[Section 2]
bar2= baz
अब, उदाहरण के लिए, जैसे इंडेक्स सूचियों का कोई तरीका है:
[Section 3]
barList={
item1,
item2
}
संबंधित प्रश्न: प्रति अनुभाग पाइथन की ConfigParser अद्वितीय कुंजी
एक बात यह है कि बहुत से लोगों को यह नहीं पता कि बहु-लाइन कॉन्फ़िगरेशन-मानों की अनुमति है। उदाहरण के लिए:
;test.ini
[hello]
barlist =
item1
item2
config.get('hello','barlist')
अब होगा:
"\nitem1\nitem2"
जो आप आसानी से splitlines विधि के साथ विभाजित कर सकते हैं (खाली वस्तुओं को फ़िल्टर करना न भूलें)।
अगर हम पिरामिड जैसे बड़े ढांचे को देखते हैं तो वे इस तकनीक का उपयोग कर रहे हैं:
def aslist_cronly(value):
if isinstance(value, string_types):
value = filter(None, [x.strip() for x in value.splitlines()])
return list(value)
def aslist(value, flatten=True):
""" Return a list of strings, separating the input based on newlines
and, if flatten=True (the default), also split on spaces within
each line."""
values = aslist_cronly(value)
if not flatten:
return values
result = []
for value in values:
subvalues = value.split()
result.extend(subvalues)
return result
स्वयं, मैं शायद ConfigParser का विस्तार करूंगा यदि यह आपके लिए एक आम बात है:
class MyConfigParser(ConfigParser):
def getlist(self,section,option):
value = self.get(section,option)
return list(filter(None, (x.strip() for x in value.splitlines())))
def getlistint(self,section,option):
return [int(x) for x in self.getlist(section,option)]
ध्यान दें कि इस तकनीक का उपयोग करते समय देखने के लिए कुछ चीजें हैं
- नई लाइनें जो आइटम हैं, व्हाइटस्पेस से शुरू होनी चाहिए (उदाहरण के लिए एक स्पेस या टैब)
- व्हाइटस्पेस से शुरू होने वाली सभी निम्न पंक्तियों को पिछले आइटम का हिस्सा माना जाता है। इसके अलावा यदि इसमें एक = चिह्न है या यदि यह एक के साथ शुरू होता है; व्हाइटस्पेस के बाद।
कॉन्फ़िगरेशन पार्सर द्वारा क्रमिकरण के लिए केवल आदिम प्रकार समर्थित हैं। मैं उस तरह की आवश्यकता के लिए जेएसओएन या वाईएएमएल का उपयोग करूंगा।
मुझे अतीत में एक ही समस्या का सामना करना पड़ा। यदि आपको अधिक जटिल सूचियों की आवश्यकता है, तो ConfigParser से विरासत में अपना स्वयं का पार्सर बनाने पर विचार करें। फिर आप उस विधि के साथ प्राप्त विधि को ओवरराइट करेंगे:
def get(self, section, option):
""" Get a parameter
if the returning value is a list, convert string value to a python list"""
value = SafeConfigParser.get(self, section, option)
if (value[0] == "[") and (value[-1] == "]"):
return eval(value)
else:
return value
इस समाधान के साथ आप अपनी कॉन्फ़िगरेशन फ़ाइल में शब्दकोश परिभाषित करने में भी सक्षम होंगे।
लेकिन सावधान रहना! यह सुरक्षित नहीं है: इसका मतलब है कि कोई भी आपकी कॉन्फ़िगरेशन फ़ाइल के माध्यम से कोड चला सकता है। अगर सुरक्षा आपके प्रोजेक्ट में कोई समस्या नहीं है, तो मैं सीधे पाइथन कक्षाओं को कॉन्फ़िगरेशन फ़ाइलों के रूप में उपयोग करने पर विचार करूंगा। ConfigParser फ़ाइल की तुलना में निम्नलिखित अधिक शक्तिशाली और व्यर्थ है:
class Section
bar = foo
class Section2
bar2 = baz
class Section3
barList=[ item1, item2 ]
यदि आप सचमुच एक सूची में गुजरना चाहते हैं तो आप इसका उपयोग कर सकते हैं:
ast.literal_eval()
उदाहरण के लिए कॉन्फ़िगरेशन:
[section]
option=["item1","item2","item3"]
कोड है:
import ConfigParser
import ast
my_list = ast.literal_eval(config.get("section", "option"))
print(type(my_list))
print(my_list)
उत्पादन:
<type'list'>
["item1","item2","item3"]
सूचियों के लिए मैं यही उपयोग करता हूं:
कॉन्फ़िगर फ़ाइल सामग्री:
[sect]
alist = a
b
c
कोड:
l = config.get('sect', 'alist').split('\n')
यह तारों के लिए काम करता है
संख्याओं के मामले में
कॉन्फ़िगरेशन सामग्री:
nlist = 1
2
3
कोड:
nl = config.get('sect', 'alist').split('\n')
l = [int(nl) for x in nl]
धन्यवाद।
import ConfigParser
import os
class Parser(object):
"""attributes may need additional manipulation"""
def __init__(self, section):
"""section to retun all options on, formatted as an object
transforms all comma-delimited options to lists
comma-delimited lists with colons are transformed to dicts
dicts will have values expressed as lists, no matter the length
"""
c = ConfigParser.RawConfigParser()
c.read(os.path.join(os.path.dirname(__file__), 'config.cfg'))
self.section_name = section
self.__dict__.update({k:v for k, v in c.items(section)})
#transform all ',' into lists, all ':' into dicts
for key, value in self.__dict__.items():
if value.find(':') > 0:
#dict
vals = value.split(',')
dicts = [{k:v} for k, v in [d.split(':') for d in vals]]
merged = {}
for d in dicts:
for k, v in d.items():
merged.setdefault(k, []).append(v)
self.__dict__[key] = merged
elif value.find(',') > 0:
#list
self.__dict__[key] = value.split(',')
तो अब मेरी config.cfg
फ़ाइल, जो इस तरह दिख सकती है:
[server]
credentials=username:admin,password:$3<r3t
loggingdirs=/tmp/logs,~/logs,/var/lib/www/logs
timeoutwait=15
मेरी छोटी परियोजना के लिए अच्छी तरह से अनाज-पर्याप्त वस्तुओं में पार्स किया जा सकता है।
>>> import config
>>> my_server = config.Parser('server')
>>> my_server.credentials
{'username': ['admin'], 'password', ['$3<r3t']}
>>> my_server.loggingdirs:
['/tmp/logs', '~/logs', '/var/lib/www/logs']
>>> my_server.timeoutwait
'15'
यह सरल कॉन्फ़िगरेशन के बहुत तेज़ पार्सिंग के लिए है, आप Parser
से लौटाई गई ऑब्जेक्ट को बदलने के बिना इनट्स, बूल और अन्य प्रकार के आउटपुट लाने की क्षमता खो देते हैं, या पार्सर क्लास द्वारा कहीं और पार्सिंग जॉब को फिर से कर सकते हैं।