Configparser 偶尔 Returns 空结果

Configparser Occasionally Returns Empty Result

我正在使用 Python configparser 从 ini 文件读取配置。 95% 的时间,它都能完美运行。如果不对 ini 文件进行任何更改(例如,在回归测试的中间),configparser 将开始返回空结果,然后在搜索嵌套配置时当然会出现关键错误。

这表明这不是 ini 文件的问题,因为它没有更改,而且它偶尔会发生。一旦问题发生,它会在所有对配置解析器的调用中继续发生,直到我终止程序并重新运行它。

我正在阅读配置:

try:
    path = os.path.dirname(os.path.realpath(__file__))
    kml_ini = '/'.join([path, 'kml.ini'])
    config = configparser.ConfigParser()
    config.read(kml_ini)
    db_conn_returnable = config['database']['db_connection'].strip()
except Exception as e:
    print(e)        
    traceback.print_exc(file=sys.stdout)
    pprint.pprint(config.sections())
    pprint.pprint({section: dict(config.items(section)) for section in config.sections()})

我遇到错误: 文件“/home/sahmed/anaconda3/envs/kml/lib/python3.6/configparser.py”,第 959 行,在 getitem 中 键错误:'database'

我的 ini 文件如下所示:

[api]
server_debug=False
log_level=info
n_workers=10

[database]
db_connection=http://1.1.1.1:9191
user=admin
pass=whateverman

[cluster]
default_workers=3

我最初的想法是一个线程问题,因为我有 8 个线程不断地访问这个配置文件(虽然它没有意义......我们只读)所以我什至在读取上放了一个紧固件块,仍然没有运气。什么可能导致这种情况?

我可以用你提供的代码复制问题的唯一方法是,如果我在代码中强行更改工作目录。

我把这个放在一起来测试问题:

from time import sleep
import configparser
import os

def readINI():
    try:
        path = os.path.dirname(os.path.realpath(__file__))
        ini = '/'.join([path, "test.ini"])
        config = configparser.ConfigParser()
        config.read(ini)
        string = config["things"]["abc"]
        print(string)
    except Exception as e:
        print("Error: {}".format(e))

count = 0
while True:
    count +=1
    readINI()
    sleep(1)
    if count % 3 == 0:
        os.chdir("..")
    elif count > 1 and count % 3 == 1:
        os.chdir("./TestFolder")

test.ini 很简单,只有两行:

[things]
abc=123

我将这两个文件放在同一个文件夹中,并在 "root" 文件夹和包含这些文件的 TestFolder 之间来回移动。如果您 raise 异常而不只是打印它,那么您将收到相同的错误消息。

请确认您没有在代码执行期间意外更改工作目录,并查看这是否确实是问题的原因。

我已经解决了这个问题。 Python 记录器提取了太多文件描述符,用尽了最大限制(在一个经常调用的函数中有一个 getLogger(),而不是全局函数)——所以整个 Python 进程无法打开配置文件。

这里的一般答案是,ConfigParser 当然会面临整体系统问题,在这种情况下,它可能无法读取它可以更早读取的文件。不是因为文件本身,而是因为达到了整体系统限制。