使用循环在.ini文件中赋值已知数量的变量

2 投票
2 回答
1121 浏览
提问于 2025-04-17 17:08

编辑 - 我已经找到了解决我问题的方法,答案在页面底部。

我有一个 .ini 文件,里面包含了不确定数量的变量,这些变量是通过一个 Python 脚本在 IRC 界面上创建的。

这个 .ini 文件的格式如下:

[varables]
0 = example
1 = example2
2 = exapmle3
#and so on.

我想对 .ini 文件中的变量做的事情是 把每一个变量都添加到一个列表里。

这是我在主 Python 文件中用来尝试实现这个目标的代码:(不是整个文件,只是用来完成这个任务的部分。)

import ConfigParser
import os

#Config parser: 
class UnknownValue(Exception): pass
def replace_line(old_line, new_line):
    f = open("setup.ini")
    for line in f:
        line = os.linesep.join([s for s in line.splitlines() if s])
        if line == old_line:
            f1 = open("setup.ini",'r')
            stuff = f1.read()
            f1.close()
            new_stuff = re.sub(old_line,new_line,stuff)
            f = open("setup.ini",'w')
            f.write(new_stuff)
            f.close()        
def get_options(filename):
    config = ConfigParser.ConfigParser()
    try:
        config.read(filename)
    except ConfigParser.ParsingError, e:
        pass
    sections = config.sections()
    output = {}
    for section in sections:
        output[section] = {}
        for opt in config.options(section):
            value = config.get(section, opt)
            output[section][opt] = value
    return output

bot_owners = []#this becomes a list with every varable in the .ini file.


#gets the number of varables to be set, then loops appending each entry into their corosponding lists for later use.
setup_file = get_options("owner.ini")
num_lines = (sum(1 for line in open('owner.ini'))-1)#gets amount of varables in the file, and removes 1 for the header tag.
print "lines ", num_lines
x = 0
while x != num_lines:
    #loops through appending all the varables inside of the .ini file to the list 'bot_owners'
    y = str(x)
    bot_owners.append(setup_file['owners'][y])#this fails becuase it can't take a varable as a argument?
    x += 1

print (bot_owners)
print (num_lines)

我通过这一行代码来找出 .ini 文件中变量的数量:

num_lines = (sum(1 for line in open('owner.ini'))-1)#gets amount of varables in the file, and removes 1 for the header tag.

我可以通过这样把每个变量添加到列表中:

bot_owners.append(setup_file['owners']['0'])
bot_owners.append(setup_file['owners']['1'])
bot_owners.append(setup_file['owners']['2'])
#ect

但这需要我知道 .ini 文件中变量的数量,而我无法知道这个数量。如果这样做就太傻了,因为这会限制 .ini 文件可以包含的变量数量,而且需要写很多代码,其实可以更简单。

if num_lines == 1:    
    bot_owners.append(setup_file['owners']['0'])
elif num_lines == 2:
    bot_owners.append(setup_file['owners']['1'])
elif num_lines == 3:
    bot_owners.append(setup_file['owners']['2'])
#ect

不过这个代码的问题在于我的循环

x = 0 #what varable is going to be appended
while x != num_lines:
    #loops through appending all the varables inside of the .ini file to the list 'bot_owners'
    y = str(x)
    bot_owners.append(setup_file['owners'][y]) #<-- THE PROBLEM
    x += 1

bot_owners.append(setup_file['owners'][y]) 这一行出现了以下错误:

KeyError: '0'

在查看了 Python 的 configParser 库文档 后,如果我没理解错,这个错误是因为第二个参数 [y],因为变量不能作为参数使用,即使这个变量的值是字符串 "1",但是 bot_owners.append(setup_file['owners']["1"]) 是可以工作的。

我在这里想问的是,是否有其他方法可以做到这一点,或者我该如何使用循环将 .ini 文件中的每个变量添加到列表中。

2 个回答

0

经过一段时间的尝试和阅读关于 ConfigParser 的所有文档,我终于找到了一个方法,可以在不使用行分隔符的情况下完成这个任务。

假设我有一个这样的 .ini 文件:

[things]
1 = not relavant at all
[more_things]
42 = don't need this
[owners]
1 = test
2 = tesing123

我可以用下面的方式,把所有在 [owners] 下存储的变量都添加进来。

import ConfigParser

config = ConfigParser.ConfigParser()
#File with the owner varables stored.
config.read('test.ini')
bot_owners = []

#Make sure the data is under the correct header.
if config.has_section('owners') == True:
    #find all the options under the [owners] header.
    data_points = config.options('owners')

    #Append the value assigned to the options to bot_owners
    for var in data_points:
        bot_owners.append(config.get('owners', var))

print bot_owners

这样就能得到 bot_owners 的值为 ['test', 'tesing123']

3

很遗憾,ConfigParser 并不真正支持列表。

如果你能找到一个安全的字符作为分隔符,那么一个不错的解决办法就是把列表打包成一个用分隔符分开的字符串,然后在读取配置文件时再把这个字符串拆开。

如果用逗号作为分隔符的话,可以这样做:

[MYSECTION]
mylist = item1,item2,item3

然后在你的代码中使用 config.get('MYSECTION', 'mylist').split(',') 来获取列表。

另外,支持多行选项。这样的话就可以像这样:

[MYSECTION]
mylist = 
    item1
    item2

在你的代码中可以使用 str.splitlines() 来处理。

撰写回答