ConfigParser and section with values without keys

2019-08-01 09:29发布

I'm just wondering. Is there any chance to create section in *.ini file to store only values without keys? I'm to store list of used ports in localhost and other servers and my list looks like this:

[servers]
localhost:1111
localhost:2222
localhost:3333
someserver:2222
someserver:3333

For now python treats server name as a key and port as value. But worst thing is that calling

print config.items('servers')

Returns me only this:

localhost:3333
someserver:3333

which is wrong, but I could handle it by replacing : in config but still section needs key for values. Any idea how to do it right?

5条回答
\"骚年 ilove
2楼-- · 2019-08-01 09:52

If you can, please change the format like this:

[servers]
localhost:1111,2222,3333
someserver:4444,5555,6666

While you read, read the key as server name and convert the value from the file as list from string through value.split(','). It will be easy for you to check for the port.

查看更多
不美不萌又怎样
3楼-- · 2019-08-01 10:00

In my opinion it would be better to use an xml rather than an ini ... is this an alternative to you?

查看更多
【Aperson】
4楼-- · 2019-08-01 10:12

I don't think you can make ConfigParser treat colons as anything but key/value delimiters. Thus, if you use colons, the hostnames will be interpreted as keys, which won't work for you because they are not unique. So you will probably have to change colons to something else. Then your entries will be unique. ConfigParser supports keys without values:

In [1]: from ConfigParser import ConfigParser

In [2]: cp = ConfigParser(allow_no_value=True)

In [3]: cp.read('foo.conf')
Out[3]: ['foo.conf']

In [4]: cp.items('servers')
Out[4]: 
[('localhost;1111', None),
 ('localhost;2222', None),
 ('localhost;3333', None),
 ('someserver;2222', None),
 ('someserver;3333', None)]

Another option is to add a unique ID to each line and also separate it by a colon. The rest will then become the value:

In [1]: from ConfigParser import ConfigParser

In [2]: cp = ConfigParser()

In [3]: cp.read('foo.conf')
Out[3]: ['foo.conf']

In [4]: cp.items('servers')
Out[4]: 
[('1', 'localhost:1111'),
 ('2', 'localhost:2222'),
 ('3', 'localhost:3333'),
 ('4', 'someserver:2222'),
 ('5', 'someserver:3333')]
查看更多
够拽才男人
5楼-- · 2019-08-01 10:15

You have the option allow_no_value, but you can not avoid ":" being a value separator, this is at ConfigParser.py:

OPTCRE = re.compile(
    r'(?P<option>[^:=\s][^:=]*)'          # very permissive!
    r'\s*(?P<vi>[:=])\s*'                 # any number of space/tab,
                                          # followed by separator
                                          # (either : or =), followed
                                          # by any # space/tab
    r'(?P<value>.*)$'                     # everything up to eol
    )

The only solution that comes to my mind:

[servers]

s1 = localhost:1111
s2 = localhost:2222
s3 = localhost:3333
s4 = someserver:2222
s5 = someserver:3333
查看更多
干净又极端
6楼-- · 2019-08-01 10:17

You could store the servers in a comma separated list,

[servers] 
server_list = localhost:1111, localhost:2222, localhost:3333, someserver:2222, someserver:3333

the read it into a list like

from ConfigParser import ConfigParser

cp = ConfigParser()
cp.read('derp.config')
print cp.items('servers')[0][1].split(', ')

which outputs

['localhost:1111', 'localhost:2222', 'localhost:3333', 'someserver:2222', 'someserver:3333']
查看更多
登录 后发表回答