【问题标题】:Configparser Occasionally Returns Empty ResultConfigparser 偶尔返回空结果
【发布时间】:2020-07-29 09:01:51
【问题描述】:

我正在使用 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()})

我收到错误: getitem 中的文件“/home/sahmed/anaconda3/envs/kml/lib/python3.6/configparser.py”,第 959 行 KeyError: '数据库'

我的 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 个线程不断地访问这个配置文件(虽然它没有意义......我们只是在阅读)所以我什至在阅读器上放了一个紧固件块,仍然没有运气。什么可能导致这种情况?

【问题讨论】:

  • 完全不相关,但您可能想改用os.path.join(path, "kml.ini")
  • 注意,而不是 kml_ini = '/'.join([path, 'kml.ini']) 我也使用了完整的绝对路径,但仍然有同样的失败。
  • 如果您对硬编码路径也有同样的问题,那么原因确实在其他地方 - 但是如果您希望得到任何有用的答案,您必须提供正确的 minimal reproducible example

标签: python configparser


【解决方案1】:

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

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

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

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

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

【讨论】:

  • 我确认观察。作为一般规则,请避免在代码中使用 chdir。
  • 感谢您的引导,让我通过查看下面的行并查看路径是否更改来检查理论。 ini = '/'.join([path, "test.ini"])
  • 我试图通过打印正在读取的完整路径来测试这个理论(认为客户端程序可能正在更改导致此问题的目录。但是,从中读取 ini 文件的完整路径始终是整个文件都是相同的——无论是在它工作时还是在它停止工作之后。所以我认为这不是我的原因。
  • 我将此答案标记为正确,因为这是 ConfigParser 直接失败的唯一 direct 方式。请注意,在我的情况下,原因实际上是完全不同的——Python 记录器提取了太多文件描述符并耗尽了最大限制——因此整个 Python 进程无法打开配置文件。
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-17
    • 2018-10-29
    • 2015-08-27
    • 2014-01-04
    • 2011-06-11
    • 2015-02-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多