簡體   English   中英

如何從 Python ConfigParser .items() 中排除 DEFAULT?

[英]How to exclude DEFAULTs from Python ConfigParser .items()?

我正在使用 ConfigParser 從配置文件加載數據,如下所示:

測試.conf:

[myfiles]
fileone: %(datadir)s/somefile.foo
filetwo: %(datadir)s/nudderfile.foo

加載.py:

import ConfigParser

config = ConfigParser.ConfigParser({'datadir': '/tmp'})
config.read('test.conf')

print config.items('myfiles')
print config.get('myfiles', 'datadir')

輸出:

$ python load.py 
[('datadir', '/tmp'), ('filetwo', '/tmp/nudderfile.foo'), ('fileone', '/tmp/somefile.foo')]
/tmp

我很驚訝變量替換的默認值('datadir', '/tmp')作為 . items().get()返回,就好像它們是配置文件中的值一樣。 這種行為是預期的嗎? 任何變通辦法,以便我可以簡單地迭代.items()而無需在其中獲取默認字典值,但仍使用魔術插值?

參考: http : //docs.python.org/library/configparser.html

謝謝!

更新:有人指出這是預期的行為:默認值就像配置文件中的任何其他名稱/值對一樣。 同樣,配置文件中的名稱/值對也可用於“魔術插值”,因此如果我定義:

foo: bar
zap: %(foo)snowl

我會得到[... ('zap': 'barnowl')]

這非常簡潔,但我仍然想知道我是否可以完成我想要完成的任務:在我的配置文件中迭代名稱/值對,使用變量插值,沒有默認值。

我的具體情況是這樣的:我想用{basedir: '/foo/bar'}類的東西初始化配置對象,因為某些文件的絕對路徑因安裝而異。 然后我需要將該配置對象傳遞給並讓各種其他類遍歷文件。 我不希望讀取配置的每個類都必須知道它是用某些默認值初始化的,並且應該忽略它們,因為它們不是實際文件。 這可能嗎? 有什么方法可以隱藏 .item() 和 .get() 的默認值但仍然有插值? 謝謝!

一般來說,我發現configparser.Configparser類非常有用,但也很缺乏。 其他人也有

然而,它可以被子類化和擴展,有時很好,有時不太好(=非常依賴於實現)

這是您的問題的解決方案,已在 Python3 中測試:

class ConfigParser(configparser.ConfigParser):
    """Can get options() without defaults
    """
    def options(self, section, no_defaults=False, **kwargs):
        if no_defaults:
            try:
                return list(self._sections[section].keys())
            except KeyError:
                raise NoSectionError(section)
        else:
            return super().options(section, **kwargs)

這是不好的例子之一,因為它部分復制options() 的源代碼 如果 configparser 基類RawConfigParser提供一個內部 getter 選項_options(self, section) ,它將合並異常轉換,以及一個將使用它的options() ,那就更好了。 然后,在子類化中我們可以重用_options()

對於 Python 2,我相信唯一的變化是super()調用super(ConfigParser,self)

然后您可以使用:

print config.options('myfiles', no_defaults=True)

並且還使用該列表進行迭代。

你不能過濾掉默認值嗎?

例如:

filtered_items = [x for x in config.items('myfiles') if x[0] not in config.defaults()]

嘗試這個:

config = ConfigParser.ConfigParser({'blahblahblah': 'blah'})
config.read('test.conf')

blahblahblah鍵也將出現在items ,不是因為它是 .ini 文件中的模板,而是因為您將其指定為默認值。 這就是 ConfigParser 處理默認值的方式:如果在文件中找不到它們,它會分配它們的默認值。

所以在我看來你在這里有一個簡單的概念混淆。

下面應該只給你myfiles部分中的鍵/值對,而不列出DEFAULT 中的那些:

list(set(config.items('myfiles'))-set(config.items('DEFAULT')))

我正在使用ConfigParser從配置文件中加載數據,如下所示:

test.conf:

[myfiles]
fileone: %(datadir)s/somefile.foo
filetwo: %(datadir)s/nudderfile.foo

load.py:

import ConfigParser

config = ConfigParser.ConfigParser({'datadir': '/tmp'})
config.read('test.conf')

print config.items('myfiles')
print config.get('myfiles', 'datadir')

輸出:

$ python load.py 
[('datadir', '/tmp'), ('filetwo', '/tmp/nudderfile.foo'), ('fileone', '/tmp/somefile.foo')]
/tmp

我很驚訝變量替換的默認值('datadir', '/tmp')作為的一部分出現。 items().get()返回,就好像它們是配置文件中的值一樣。 這是預期的行為嗎? 任何變通辦法,以便我可以簡單地迭代.items()而不在其中獲取默認字典值,但仍使用魔術插值法嗎?

參考: http : //docs.python.org/library/configparser.html

謝謝!

更新:已經指出這是預期的行為:默認值與配置文件中的任何其他名稱/值對一樣。 同樣,配置文件中的名稱/值對也可用於“魔術插值”,因此如果我定義:

foo: bar
zap: %(foo)snowl

我會得到[... ('zap': 'barnowl')]

那很整潔,但是我仍然想知道我是否可以完成我想完成的工作:遍歷配置文件中的名稱/值對,使用變量插值,而不使用默認值。

我的具體情況是這樣的:我想用{basedir: '/foo/bar'}類的東西來初始化config對象,因為某些文件的絕對路徑因安裝而異。 然后,我需要將該配置對象傳遞給,並讓其他各種類遍歷文件。 我不希望每個讀取配置的類都必須知道它是使用某些默認值初始化的,並且應該忽略它們,因為它們不是實際文件。 這可能嗎? 有什么辦法可以從.item()和.get()中隱藏默認值,但是仍然具有插值功能? 謝謝!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM