configparser --- 配置檔案解析器

原始碼: Lib/configparser.py


該模組提供 ConfigParser 類,它實現了一種基本的配置語言,其結構類似於 Microsoft Windows INI 檔案。你可以用它來編寫 Python 程式,讓終端使用者可以輕鬆地對其進行自定義。

備註

此庫*不會*解釋或寫入 Windows 登錄檔擴充套件版 INI 語法中使用的值型別字首。

參見

模組 tomllib

TOML 是一種為應用程式配置檔案精心設計的格式。它專門設計為 INI 的改進版本。

模組 shlex

支援建立類似 Unix shell 的迷你語言,也可用於應用程式配置檔案。

模組 json

json 模組實現了 JavaScript 語法的一個子集,有時用於配置,但不支援註釋。

快速上手

讓我們看一個非常基本的配置檔案,如下所示

[DEFAULT]
ServerAliveInterval = 45
Compression = yes
CompressionLevel = 9
ForwardX11 = yes

[forge.example]
User = hg

[topsecret.server.example]
Port = 50022
ForwardX11 = no

INI 檔案的結構在下一節中描述。本質上,檔案由多個節(section)組成,每個節包含帶有值的鍵(key)。configparser 類可以讀寫此類檔案。讓我們從以程式設計方式建立上述配置檔案開始。

>>> import configparser
>>> config = configparser.ConfigParser()
>>> config['DEFAULT'] = {'ServerAliveInterval': '45',
...                      'Compression': 'yes',
...                      'CompressionLevel': '9'}
>>> config['forge.example'] = {}
>>> config['forge.example']['User'] = 'hg'
>>> config['topsecret.server.example'] = {}
>>> topsecret = config['topsecret.server.example']
>>> topsecret['Port'] = '50022'     # mutates the parser
>>> topsecret['ForwardX11'] = 'no'  # same here
>>> config['DEFAULT']['ForwardX11'] = 'yes'
>>> with open('example.ini', 'w') as configfile:
...   config.write(configfile)
...

如你所見,我們可以像對待字典一樣對待配置解析器。雖然存在差異,如後面所述,但其行為與你期望的字典非常接近。

現在我們已經建立並儲存了一個配置檔案,讓我們把它讀回來並探究它所包含的資料。

>>> config = configparser.ConfigParser()
>>> config.sections()
[]
>>> config.read('example.ini')
['example.ini']
>>> config.sections()
['forge.example', 'topsecret.server.example']
>>> 'forge.example' in config
True
>>> 'python.org' in config
False
>>> config['forge.example']['User']
'hg'
>>> config['DEFAULT']['Compression']
'yes'
>>> topsecret = config['topsecret.server.example']
>>> topsecret['ForwardX11']
'no'
>>> topsecret['Port']
'50022'
>>> for key in config['forge.example']:
...     print(key)
user
compressionlevel
serveraliveinterval
compression
forwardx11
>>> config['forge.example']['ForwardX11']
'yes'

如上所示,API 非常直觀。唯一有點奇妙的地方是 DEFAULT 節,它為所有其他節提供預設值 [1]。另請注意,節中的鍵是大小寫不敏感的,並以小寫形式儲存 [1]

可以將多個配置讀入單個 ConfigParser 中,其中最近新增的配置具有最高優先順序。任何衝突的鍵都將取自較新的配置,而先前存在的鍵則被保留。下面的示例讀取了一個 override.ini 檔案,它將覆蓋 example.ini 檔案中的任何衝突鍵。

[DEFAULT]
ServerAliveInterval = -1
>>> config_override = configparser.ConfigParser()
>>> config_override['DEFAULT'] = {'ServerAliveInterval': '-1'}
>>> with open('override.ini', 'w') as configfile:
...     config_override.write(configfile)
...
>>> config_override = configparser.ConfigParser()
>>> config_override.read(['example.ini', 'override.ini'])
['example.ini', 'override.ini']
>>> print(config_override.get('DEFAULT', 'ServerAliveInterval'))
-1

此行為等同於呼叫 ConfigParser.read() 並將多個檔案傳遞給 filenames 引數。

支援的資料型別

配置解析器不會猜測配置檔案中值的資料型別,總是將它們作為字串在內部儲存。這意味著如果你需要其他資料型別,應該自己進行轉換

>>> int(topsecret['Port'])
50022
>>> float(topsecret['CompressionLevel'])
9.0

由於這個任務非常普遍,配置解析器提供了一系列方便的 getter 方法來處理整數、浮點數和布林值。最後一個最有趣,因為簡單地將值傳遞給 bool() 是沒有用的,因為 bool('False') 仍然是 True。這就是為什麼配置解析器還提供了 getboolean()。此方法不區分大小寫,並識別 'yes'/'no''on'/'off''true'/'false''1'/'0' 的布林值 [1]。例如

>>> topsecret.getboolean('ForwardX11')
False
>>> config['forge.example'].getboolean('ForwardX11')
True
>>> config.getboolean('forge.example', 'Compression')
True

除了 getboolean(),配置解析器還提供了等效的 getint()getfloat() 方法。你可以註冊自己的轉換器並自定義已提供的轉換器。[1]

回退值

與字典一樣,你可以使用節的 get() 方法來提供回退值

>>> topsecret.get('Port')
'50022'
>>> topsecret.get('CompressionLevel')
'9'
>>> topsecret.get('Cipher')
>>> topsecret.get('Cipher', '3des-cbc')
'3des-cbc'

請注意,預設值的優先順序高於回退值。例如,在我們的示例中,'CompressionLevel' 鍵只在 'DEFAULT' 節中指定。如果我們嘗試從 'topsecret.server.example' 節中獲取它,我們總是會得到預設值,即使我們指定了回退值

>>> topsecret.get('CompressionLevel', '3')
'9'

還有一點需要注意的是,解析器級別的 get() 方法提供了一個自定義的、更復雜的介面,為向後相容而保留。使用此方法時,可以透過 fallback 僅關鍵字引數提供回退值

>>> config.get('forge.example', 'monster',
...            fallback='No such things as monsters')
'No such things as monsters'

相同的 fallback 引數可用於 getint()getfloat()getboolean() 方法,例如

>>> 'BatchMode' in topsecret
False
>>> topsecret.getboolean('BatchMode', fallback=True)
True
>>> config['DEFAULT']['BatchMode'] = 'no'
>>> topsecret.getboolean('BatchMode', fallback=True)
False

支援的 INI 檔案結構

配置檔案由多個節(section)組成,每個節由 [section] 標頭引導,後面跟著由特定字串(預設為 =: [1])分隔的鍵/值條目。預設情況下,節名稱區分大小寫,但鍵不區分大小寫 [1]。鍵和值的前後空白會被移除。如果解析器配置為允許,值可以被省略 [1],在這種情況下,鍵/值分隔符也可以省略。值也可以跨越多行,只要它們的縮排比值的第一行更深。根據解析器的模式,空行可能被視作多行值的一部分或被忽略。

預設情況下,有效的節名稱可以是任何不包含“\n”的字串。要更改此設定,請參閱 ConfigParser.SECTCRE

如果解析器透過 allow_unnamed_section=True 配置為允許一個未命名的頂層節,則可以省略第一個節的名稱。在這種情況下,鍵/值可以透過 UNNAMED_SECTION 檢索,例如 config[UNNAMED_SECTION]

配置檔案可以包含註釋,註釋以特定字元為字首(預設為 #; [1])。註釋可以單獨出現在原本為空的行上,也可以縮排。[1]

例如:

[Simple Values]
key=value
spaces in keys=allowed
spaces in values=allowed as well
spaces around the delimiter = obviously
you can also use : to delimit keys from values

[All Values Are Strings]
values like this: 1000000
or this: 3.14159265359
are they treated as numbers? : no
integers, floats and booleans are held as: strings
can use the API to get converted values directly: true

[Multiline Values]
chorus: I'm a lumberjack, and I'm okay
    I sleep all night and I work all day

[No Values]
key_without_value
empty string value here =

[You can use comments]
# like this
; or this

# By default only in an empty line.
# Inline comments can be harmful because they prevent users
# from using the delimiting characters as parts of values.
# That being said, this can be customized.

    [Sections Can Be Indented]
        can_values_be_as_well = True
        does_that_mean_anything_special = False
        purpose = formatting for readability
        multiline_values = are
            handled just fine as
            long as they are indented
            deeper than the first line
            of a value
        # Did I mention we can indent comments, too?

未命名節

第一個(或唯一的)節的名稱可以省略,值可以透過 UNNAMED_SECTION 屬性檢索。

>>> config = """
... option = value
...
... [  Section 2  ]
... another = val
... """
>>> unnamed = configparser.ConfigParser(allow_unnamed_section=True)
>>> unnamed.read_string(config)
>>> unnamed.get(configparser.UNNAMED_SECTION, 'option')
'value'

值的插值

除了核心功能外,ConfigParser 還支援插值。這意味著在從 get() 呼叫返回值之前,可以對值進行預處理。

class configparser.BasicInterpolation

ConfigParser 使用的預設實現。它允許值包含格式字串,這些字串引用同一節中的其他值,或特殊預設節中的值 [1]。可以在初始化時提供額外的預設值。

例如:

[Paths]
home_dir: /Users
my_dir: %(home_dir)s/lumberjack
my_pictures: %(my_dir)s/Pictures

[Escape]
# use a %% to escape the % sign (% is the only character that needs to be escaped):
gain: 80%%

在上面的例子中,將 interpolation 設定為 BasicInterpolation()ConfigParser 會將 %(home_dir)s 解析為 home_dir 的值(在本例中為 /Users)。%(my_dir)s 實際上會解析為 /Users/lumberjack。所有插值都是按需進行的,因此引用鏈中使用的鍵不必在配置檔案中以任何特定順序指定。

如果將 interpolation 設定為 None,解析器將簡單地返回 %(my_dir)s/Pictures 作為 my_pictures 的值,以及 %(home_dir)s/lumberjack 作為 my_dir 的值。

class configparser.ExtendedInterpolation

一種替代的插值處理器,它實現了一種更高階的語法,例如在 zc.buildout 中使用。擴充套件插值使用 ${section:option} 來表示來自外部節的值。插值可以跨越多個級別。為方便起見,如果省略了 section: 部分,插值將預設為當前節(以及可能來自特殊節的預設值)。

例如,上面用基本插值指定的配置,用擴充套件插值會是這樣

[Paths]
home_dir: /Users
my_dir: ${home_dir}/lumberjack
my_pictures: ${my_dir}/Pictures

[Escape]
# use a $$ to escape the $ sign ($ is the only character that needs to be escaped):
cost: $$80

也可以獲取其他節的值

[Common]
home_dir: /Users
library_dir: /Library
system_dir: /System
macports_dir: /opt/local

[Frameworks]
Python: 3.2
path: ${Common:system_dir}/Library/Frameworks/

[Arthur]
nickname: Two Sheds
last_name: Jackson
my_dir: ${Common:home_dir}/twosheds
my_pictures: ${my_dir}/Pictures
python_dir: ${Frameworks:path}/Python/Versions/${Frameworks:Python}

對映協議訪問

在 3.2 版本加入。

對映協議訪問是一個通用名稱,用於描述允許將自定義物件像字典一樣使用的功能。在 configparser 中,對映介面的實現使用了 parser['section']['option'] 這種表示法。

特別是,parser['section'] 會返回一個該節在解析器中資料的代理。這意味著值不會被複制,而是根據需要從原始解析器中獲取。更重要的是,當在一個節代理上更改值時,它們實際上是在原始解析器中被修改的。

configparser 物件的行為儘可能接近實際的字典。對映介面是完整的,並遵循 MutableMapping ABC。但是,有幾個差異需要考慮

  • 預設情況下,節中的所有鍵都以不區分大小寫的方式訪問 [1]。例如,for option in parser["section"] 只會產生經過 optionxform 處理後的選項鍵名。預設情況下這意味著鍵名是小寫的。同時,對於一個包含鍵 'a' 的節,以下兩個表示式都返回 True

    "a" in parser["section"]
    "A" in parser["section"]
    
  • 所有節都包含 DEFAULTSECT 的值,這意味著在一個節上呼叫 .clear() 可能不會讓該節看起來是空的。這是因為預設值無法從節中刪除(因為技術上它們並不在那裡)。如果它們在節中被覆蓋,刪除會導致預設值再次可見。嘗試刪除預設值會引發 KeyError

  • DEFAULTSECT 無法從解析器中移除

    • 嘗試刪除它會引發 ValueError

    • parser.clear() 會保留它不變,

    • parser.popitem() 永遠不會返回它。

  • parser.get(section, option, **kwargs) - 第二個引數 不是 回退值。但請注意,節級別的 get() 方法既相容對映協議,也相容經典的 configparser API。

  • parser.items() 與對映協議相容(返回一個包含 DEFAULTSECT 的 section_name, section_proxy 對的列表)。但是,此方法也可以帶引數呼叫:parser.items(section, raw, vars)。後一種呼叫返回指定 sectionoption, value 對的列表,所有插值都已展開(除非提供了 raw=True)。

對映協議是在現有的傳統 API 之上實現的,因此重寫了原始介面的子類應該仍然能使對映按預期工作。

自定義解析器行為

INI 格式的變體幾乎和使用它的應用程式一樣多。configparser 在支援最大範圍的合理 INI 樣式方面做了很多努力。預設功能主要由歷史背景決定,你很可能想要自定義某些功能。

改變特定配置解析器工作方式的最常用方法是使用 __init__() 選項

  • defaults,預設值:None

    此選項接受一個鍵值對字典,這些鍵值對將最初放入 DEFAULT 節中。這為支援簡潔的配置檔案提供了一種優雅的方式,這些檔案不指定與文件化預設值相同的值。

    提示:如果要為特定節指定預設值,請在讀取實際檔案之前使用 read_dict()

  • dict_type,預設值:dict

    這個選項對對映協議的行為方式以及寫入的配置檔案的外觀有重大影響。使用標準字典時,每個節都按照它們被新增到解析器的順序儲存。節內的選項也是如此。

    可以使用替代的字典型別,例如在寫回時對節和選項進行排序。

    請注意:有多種方法可以一次性新增一組鍵值對。當你在這些操作中使用常規字典時,鍵的順序將被保留。例如

    >>> parser = configparser.ConfigParser()
    >>> parser.read_dict({'section1': {'key1': 'value1',
    ...                                'key2': 'value2',
    ...                                'key3': 'value3'},
    ...                   'section2': {'keyA': 'valueA',
    ...                                'keyB': 'valueB',
    ...                                'keyC': 'valueC'},
    ...                   'section3': {'foo': 'x',
    ...                                'bar': 'y',
    ...                                'baz': 'z'}
    ... })
    >>> parser.sections()
    ['section1', 'section2', 'section3']
    >>> [option for option in parser['section3']]
    ['foo', 'bar', 'baz']
    
  • allow_no_value,預設值:False

    已知某些配置檔案包含沒有值的設定,但其他方面符合 configparser 支援的語法。建構函式的 allow_no_value 引數可用於指示應接受此類值

    >>> import configparser
    
    >>> sample_config = """
    ... [mysqld]
    ...   user = mysql
    ...   pid-file = /var/run/mysqld/mysqld.pid
    ...   skip-external-locking
    ...   old_passwords = 1
    ...   skip-bdb
    ...   # we don't need ACID today
    ...   skip-innodb
    ... """
    >>> config = configparser.ConfigParser(allow_no_value=True)
    >>> config.read_string(sample_config)
    
    >>> # Settings with values are treated as before:
    >>> config["mysqld"]["user"]
    'mysql'
    
    >>> # Settings without values provide None:
    >>> config["mysqld"]["skip-bdb"]
    
    >>> # Settings which aren't specified still raise an error:
    >>> config["mysqld"]["does-not-exist"]
    Traceback (most recent call last):
      ...
    KeyError: 'does-not-exist'
    
  • delimiters,預設值:('=', ':')

    分隔符是在一個節內分隔鍵和值的子字串。一行中第一次出現的分隔子字串被視為分隔符。這意味著值(但不是鍵)可以包含分隔符。

    另請參閱 ConfigParser.write()space_around_delimiters 引數。

  • comment_prefixes,預設值:('#', ';')

  • inline_comment_prefixes,預設值:None

    註釋字首是表示配置檔案中有效註釋開始的字串。comment_prefixes 僅用於原本為空的行(可選擇縮排),而 inline_comment_prefixes 可用於每個有效值之後(例如節名、選項和空行)。預設情況下,內聯註釋是停用的,'#'';' 被用作整行註釋的字首。

    在 3.2 版更改: configparser 的早期版本中,行為與 comment_prefixes=('#',';')inline_comment_prefixes=(';',) 匹配。

    請注意,配置解析器不支援註釋字首的轉義,因此使用 inline_comment_prefixes 可能會阻止使用者指定包含用作註釋字首的字元的選項值。如有疑問,請避免設定 inline_comment_prefixes。在任何情況下,在多行值的行首儲存註釋字首字元的唯一方法是插值該字首,例如

    >>> from configparser import ConfigParser, ExtendedInterpolation
    >>> parser = ConfigParser(interpolation=ExtendedInterpolation())
    >>> # the default BasicInterpolation could be used as well
    >>> parser.read_string("""
    ... [DEFAULT]
    ... hash = #
    ...
    ... [hashes]
    ... shebang =
    ...   ${hash}!/usr/bin/env python
    ...   ${hash} -*- coding: utf-8 -*-
    ...
    ... extensions =
    ...   enabled_extension
    ...   another_extension
    ...   #disabled_by_comment
    ...   yet_another_extension
    ...
    ... interpolation not necessary = if # is not at line start
    ... even in multiline values = line #1
    ...   line #2
    ...   line #3
    ... """)
    >>> print(parser['hashes']['shebang'])
    
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    >>> print(parser['hashes']['extensions'])
    
    enabled_extension
    another_extension
    yet_another_extension
    >>> print(parser['hashes']['interpolation not necessary'])
    if # is not at line start
    >>> print(parser['hashes']['even in multiline values'])
    line #1
    line #2
    line #3
    
  • strict,預設值:True

    當設定為 True 時,解析器在從單個源(使用 read_file()read_string()read_dict())讀取時不允許任何節或選項重複。建議在新應用程式中使用嚴格的解析器。

    在 3.2 版更改: configparser 的先前版本中,行為與 strict=False 匹配。

  • empty_lines_in_values,預設值:True

    在配置解析器中,值可以跨越多行,只要它們的縮排比持有它們的鍵更深。預設情況下,解析器也允許空行成為值的一部分。同時,鍵本身可以任意縮排以提高可讀性。因此,當配置檔案變得龐大而複雜時,使用者很容易迷失檔案結構。例如

    [Section]
    key = multiline
      value with a gotcha
    
     this = is still a part of the multiline value of 'key'
    

    如果使用者使用比例字型編輯檔案,這可能會特別成問題。這就是為什麼當你的應用程式不需要帶有空行的值時,你應該考慮禁止它們。這將使空行每次都分割鍵。在上面的例子中,它會產生兩個鍵,keythis

  • default_section,預設值:configparser.DEFAULTSECT(即:"DEFAULT"

    允許一個特殊的預設值節用於其他節或插值目的的慣例是這個庫的一個強大概念,讓使用者可以建立複雜的宣告性配置。這個節通常被稱為 "DEFAULT",但可以自定義為指向任何其他有效的節名。一些典型的值包括:"general""common"。提供的名稱用於在從任何源讀取時識別預設節,並在將配置寫回檔案時使用。它的當前值可以使用 parser_instance.default_section 屬性檢索,並且可以在執行時修改(即,用於將檔案從一種格式轉換為另一種格式)。

  • interpolation,預設值:configparser.BasicInterpolation

    插值行為可以透過 interpolation 引數提供自定義處理程式來定製。None 可用於完全關閉插值,ExtendedInterpolation() 提供了一種受 zc.buildout 啟發的更高階的變體。更多相關內容請參閱專門的文件部分RawConfigParser 的預設值為 None

  • converters,預設值:未設定

    配置解析器提供執行型別轉換的選項值獲取器。預設實現了 getint()getfloat()getboolean()。如果需要其他獲取器,使用者可以在子類中定義它們,或傳遞一個字典,其中每個鍵是轉換器的名稱,每個值是實現該轉換的可呼叫物件。例如,傳遞 {'decimal': decimal.Decimal} 將在解析器物件和所有節代理上新增 getdecimal()。換句話說,可以同時編寫 parser_instance.getdecimal('section', 'key', fallback=0)parser_instance['section'].getdecimal('key', 0)

    如果轉換器需要訪問解析器的狀態,它可以作為配置解析器子類的一個方法來實現。如果這個方法的名稱以 get 開頭,它將在所有節代理上可用,以與字典相容的形式(參見上面的 getdecimal() 示例)。

更高階的自定義可以透過重寫這些解析器屬性的預設值來實現。預設值是在類上定義的,因此它們可以被子類或透過屬性賦值來重寫。

ConfigParser.BOOLEAN_STATES

預設情況下,使用 getboolean() 時,配置解析器將以下值視為 True'1''yes''true''on',並將以下值視為 False'0''no''false''off'。你可以透過指定一個自定義的字串及其布林結果的字典來覆蓋此行為。例如

>>> custom = configparser.ConfigParser()
>>> custom['section1'] = {'funky': 'nope'}
>>> custom['section1'].getboolean('funky')
Traceback (most recent call last):
...
ValueError: Not a boolean: nope
>>> custom.BOOLEAN_STATES = {'sure': True, 'nope': False}
>>> custom['section1'].getboolean('funky')
False

其他典型的布林值對包括 accept/rejectenabled/disabled

ConfigParser.optionxform(option)

此方法在每次讀取、獲取或設定操作時轉換選項名稱。預設實現將名稱轉換為小寫。這也意味著當寫入配置檔案時,所有鍵都將是小寫的。如果這不適用,請重寫此方法。例如

>>> config = """
... [Section1]
... Key = Value
...
... [Section2]
... AnotherKey = Value
... """
>>> typical = configparser.ConfigParser()
>>> typical.read_string(config)
>>> list(typical['Section1'].keys())
['key']
>>> list(typical['Section2'].keys())
['anotherkey']
>>> custom = configparser.RawConfigParser()
>>> custom.optionxform = lambda option: option
>>> custom.read_string(config)
>>> list(custom['Section1'].keys())
['Key']
>>> list(custom['Section2'].keys())
['AnotherKey']

備註

optionxform 函式將選項名稱轉換為規範形式。這應該是一個冪等函式:如果名稱已經是規範形式,它應該被原樣返回。

ConfigParser.SECTCRE

一個用於解析節標題的已編譯正則表示式。預設匹配 [section] 到名稱 "section"。空格被視為節名稱的一部分,因此 [  larch  ] 將被讀取為名稱為 "  larch  " 的節。如果這不適用,請重寫此屬性。例如

>>> import re
>>> config = """
... [Section 1]
... option = value
...
... [  Section 2  ]
... another = val
... """
>>> typical = configparser.ConfigParser()
>>> typical.read_string(config)
>>> typical.sections()
['Section 1', '  Section 2  ']
>>> custom = configparser.ConfigParser()
>>> custom.SECTCRE = re.compile(r"\[ *(?P<header>[^]]+?) *\]")
>>> custom.read_string(config)
>>> custom.sections()
['Section 1', 'Section 2']

備註

雖然 ConfigParser 物件也使用 OPTCRE 屬性來識別選項行,但不建議重寫它,因為這會干擾建構函式選項 allow_no_valuedelimiters

傳統 API 示例

主要出於向後相容性的考慮,configparser 也提供了一個帶有顯式 get/set 方法的傳統 API。雖然下面概述的方法有有效的用例,但對於新專案,首選對映協議訪問。傳統 API 有時更高階、更底層,甚至完全不直觀。

一個寫入配置檔案的例子

import configparser

config = configparser.RawConfigParser()

# Please note that using RawConfigParser's set functions, you can assign
# non-string values to keys internally, but will receive an error when
# attempting to write to a file or when you get it in non-raw mode. Setting
# values using the mapping protocol or ConfigParser's set() does not allow
# such assignments to take place.
config.add_section('Section1')
config.set('Section1', 'an_int', '15')
config.set('Section1', 'a_bool', 'true')
config.set('Section1', 'a_float', '3.1415')
config.set('Section1', 'baz', 'fun')
config.set('Section1', 'bar', 'Python')
config.set('Section1', 'foo', '%(bar)s is %(baz)s!')

# Writing our configuration file to 'example.cfg'
with open('example.cfg', 'w') as configfile:
    config.write(configfile)

一個再次讀取配置檔案的例子

import configparser

config = configparser.RawConfigParser()
config.read('example.cfg')

# getfloat() raises an exception if the value is not a float
# getint() and getboolean() also do this for their respective types
a_float = config.getfloat('Section1', 'a_float')
an_int = config.getint('Section1', 'an_int')
print(a_float + an_int)

# Notice that the next output does not interpolate '%(bar)s' or '%(baz)s'.
# This is because we are using a RawConfigParser().
if config.getboolean('Section1', 'a_bool'):
    print(config.get('Section1', 'foo'))

要使用插值,請使用 ConfigParser

import configparser

cfg = configparser.ConfigParser()
cfg.read('example.cfg')

# Set the optional *raw* argument of get() to True if you wish to disable
# interpolation in a single get operation.
print(cfg.get('Section1', 'foo', raw=False))  # -> "Python is fun!"
print(cfg.get('Section1', 'foo', raw=True))   # -> "%(bar)s is %(baz)s!"

# The optional *vars* argument is a dict with members that will take
# precedence in interpolation.
print(cfg.get('Section1', 'foo', vars={'bar': 'Documentation',
                                       'baz': 'evil'}))

# The optional *fallback* argument can be used to provide a fallback value
print(cfg.get('Section1', 'foo'))
      # -> "Python is fun!"

print(cfg.get('Section1', 'foo', fallback='Monty is not.'))
      # -> "Python is fun!"

print(cfg.get('Section1', 'monster', fallback='No such things as monsters.'))
      # -> "No such things as monsters."

# A bare print(cfg.get('Section1', 'monster')) would raise NoOptionError
# but we can also use:

print(cfg.get('Section1', 'monster', fallback=None))
      # -> None

兩種型別的 ConfigParsers 都提供預設值。如果在插值中使用的選項在別處沒有定義,則會使用預設值。

import configparser

# New instance with 'bar' and 'baz' defaulting to 'Life' and 'hard' each
config = configparser.ConfigParser({'bar': 'Life', 'baz': 'hard'})
config.read('example.cfg')

print(config.get('Section1', 'foo'))     # -> "Python is fun!"
config.remove_option('Section1', 'bar')
config.remove_option('Section1', 'baz')
print(config.get('Section1', 'foo'))     # -> "Life is hard!"

ConfigParser 物件

class configparser.ConfigParser(defaults=None, dict_type=dict, allow_no_value=False, *, delimiters=('=', ':'), comment_prefixes=('#', ';'), inline_comment_prefixes=None, strict=True, empty_lines_in_values=True, default_section=configparser.DEFAULTSECT, interpolation=BasicInterpolation(), converters={}, allow_unnamed_section=False)

主配置解析器。如果給定了 defaults,它將被初始化到固有預設值的字典中。如果給定了 dict_type,它將用於為節列表、節內選項和預設值建立字典物件。

如果給定了 delimiters,它將用作分隔鍵和值的子字串集。如果給定了 comment_prefixes,它將用作在原本為空的行中作為註釋字首的子字串集。註釋可以縮排。如果給定了 inline_comment_prefixes,它將用作在非空行中作為註釋字首的子字串集。

strictTrue(預設值)時,解析器在從單個源(檔案、字串或字典)讀取時不允許任何節或選項重複,會引發 DuplicateSectionErrorDuplicateOptionError。當 empty_lines_in_valuesFalse(預設:True)時,每個空行都標誌著一個選項的結束。否則,多行選項的內部空行將作為值的一部分保留。當 allow_no_valueTrue(預設:False)時,接受沒有值的選項;為這些選項保留的值是 None,並且它們在序列化時沒有尾隨的分隔符。

如果給定了 default_section,它指定了用於儲存其他節和插值目的的預設值的特殊節的名稱(通常命名為 "DEFAULT")。這個值可以在執行時使用 default_section 例項屬性來檢索和更改。這不會重新評估已經解析的配置檔案,但會在將解析的設定寫入新配置檔案時使用。

插值行為可以透過 interpolation 引數提供自定義處理程式來定製。None 可用於完全關閉插值,ExtendedInterpolation() 提供了一種受 zc.buildout 啟發的更高階的變體。更多相關內容請參閱專門的文件部分

所有用於插值的選項名稱都將透過 optionxform() 方法進行轉換,就像任何其他選項名稱引用一樣。例如,使用 optionxform() 的預設實現(將選項名稱轉換為小寫),值 foo %(bar)sfoo %(BAR)s 是等效的。

如果給定了 converters,它應該是一個字典,其中每個鍵表示型別轉換器的名稱,每個值是實現從字串到所需資料型別轉換的可呼叫物件。每個轉換器在解析器物件和節代理上都有其對應的 get*() 方法。

allow_unnamed_sectionTrue(預設:False)時,第一個節的名稱可以省略。請參閱 “未命名節”部分

可以將多個配置讀入單個 ConfigParser 中,其中最近新增的配置具有最高優先順序。任何衝突的鍵都將取自較新的配置,而先前存在的鍵則被保留。下面的示例讀取了一個 override.ini 檔案,它將覆蓋 example.ini 檔案中的任何衝突鍵。

[DEFAULT]
ServerAliveInterval = -1
>>> config_override = configparser.ConfigParser()
>>> config_override['DEFAULT'] = {'ServerAliveInterval': '-1'}
>>> with open('override.ini', 'w') as configfile:
...     config_override.write(configfile)
...
>>> config_override = configparser.ConfigParser()
>>> config_override.read(['example.ini', 'override.ini'])
['example.ini', 'override.ini']
>>> print(config_override.get('DEFAULT', 'ServerAliveInterval'))
-1

在 3.1 版更改: 預設的 dict_typecollections.OrderedDict

在 3.2 版更改: 添加了 allow_no_value, delimiters, comment_prefixes, strict, empty_lines_in_values, default_sectioninterpolation

在 3.5 版更改: 添加了 converters 引數。

在 3.7 版更改: defaults 引數透過 read_dict() 讀取,在整個解析器中提供了一致的行為:非字串的鍵和值會隱式轉換為字串。

在 3.8 版更改: 預設的 dict_typedict,因為它現在保留插入順序。

在 3.13 版更改: allow_no_valueTrue,且一個沒有值的鍵後跟一個縮排行時,會引發 MultilineContinuationError

在 3.13 版更改: 添加了 allow_unnamed_section 引數。

defaults()

返回一個包含例項級預設值的字典。

sections()

返回可用節的列表;預設節不包含在此列表中。

add_section(section)

向例項新增一個名為 section 的節。如果已存在同名節,則引發 DuplicateSectionError。如果傳遞了預設節名稱,則引發 ValueError。節的名稱必須是字串;如果不是,則引發 TypeError

在 3.2 版更改: 非字串的節名稱會引發 TypeError

has_section(section)

指示名為 section 的節是否存在於配置中。預設節不被承認。

options(section)

返回指定 section 中可用選項的列表。

has_option(section, option)

如果給定的 section 存在,並且包含給定的 option,則返回 True;否則返回 False。如果指定的 sectionNone 或空字串,則假定為 DEFAULT。

read(filenames, encoding=None)

嘗試讀取並解析一個可迭代的檔名,返回一個成功解析的檔名列表。

如果 filenames 是一個字串、一個 bytes 物件或一個類路徑物件,它被視為單個檔名。如果 filenames 中命名的檔案無法開啟,該檔案將被忽略。這樣設計是為了讓你能指定一個潛在配置檔案位置的可迭代物件(例如,當前目錄、使用者主目錄和某個系統級目錄),並且可迭代物件中所有存在的配置檔案都將被讀取。

如果所有指定的檔案都不存在,ConfigParser 例項將包含一個空資料集。需要從檔案中載入初始值的應用程式應在呼叫 read() 讀取任何可選檔案之前,使用 read_file() 載入所需的檔案

import configparser, os

config = configparser.ConfigParser()
config.read_file(open('defaults.cfg'))
config.read(['site.cfg', os.path.expanduser('~/.myapp.cfg')],
            encoding='cp1250')

在 3.2 版更改: 添加了 encoding 引數。以前,所有檔案都使用 open() 的預設編碼讀取。

在 3.6.1 版更改: filenames 引數接受一個類路徑物件

在 3.7 版更改: filenames 引數接受一個 bytes 物件。

read_file(f, source=None)

f 中讀取並解析配置資料,f 必須是一個產生 Unicode 字串的可迭代物件(例如以文字模式開啟的檔案)。

可選引數 source 指定正在讀取的檔案的名稱。如果未給出且 f 有一個 name 屬性,則該屬性被用作 source;預設值為 '<???>'

3.2 新版功能: 取代 readfp()

read_string(string, source='<string>')

從字串中解析配置資料。

可選引數 source 指定了所傳遞字串的上下文特定名稱。如果未給出,則使用 '<string>'。這通常應該是一個檔案系統路徑或 URL。

在 3.2 版本加入。

read_dict(dictionary, source='<dict>')

從任何提供類似字典的 items() 方法的物件載入配置。鍵是節名,值是包含節中應存在的鍵和值的字典。如果使用的字典型別保留順序,則節及其鍵將按順序新增。值會自動轉換為字串。

可選引數 source 指定了所傳遞字典的上下文特定名稱。如果未給出,則使用 <dict>

此方法可用於在解析器之間複製狀態。

在 3.2 版本加入。

get(section, option, *, raw=False, vars=None[, fallback])

獲取指定 sectionoption 值。如果提供了 vars,它必須是一個字典。option 將按順序在 vars(如果提供)、sectionDEFAULTSECT 中查詢。如果未找到鍵且提供了 fallback,則使用它作為回退值。可以將 None 作為 fallback 值提供。

除非 raw 引數為 true,否則返回值中的所有 '%' 插值都會被展開。插值鍵的值會以與選項相同的方式進行查詢。

在 3.2 版更改: 引數 rawvarsfallback 僅為關鍵字引數,以保護使用者不嘗試將第三個引數用作 fallback 回退(特別是在使用對映協議時)。

getint(section, option, *, raw=False, vars=None[, fallback])

一個方便的方法,將指定 section 中的 option 強制轉換為整數。有關 rawvarsfallback 的解釋,請參見 get()

getfloat(section, option, *, raw=False, vars=None[, fallback])

一個方便的方法,將指定 section 中的 option 強制轉換為浮點數。有關 rawvarsfallback 的解釋,請參見 get()

getboolean(section, option, *, raw=False, vars=None[, fallback])

一個方便的方法,將指定 section 中的 option 強制轉換為布林值。請注意,該選項可接受的值為 '1''yes''true''on',這些值會使此方法返回 True;以及 '0''no''false''off',這些值會使其返回 False。這些字串值的檢查不區分大小寫。任何其他值都會導致它引發 ValueError。有關 rawvarsfallback 的解釋,請參見 get()

items(raw=False, vars=None)
items(section, raw=False, vars=None)

當未提供 section 時,返回一個 section_name, section_proxy 對的列表,包括 DEFAULTSECT。

否則,返回給定 section 中選項的 name, value 對的列表。可選引數的含義與 get() 方法相同。

在 3.8 版更改: vars 中存在的項不再出現在結果中。以前的行為將實際的解析器選項與為插值提供的變數混合在一起。

set(section, option, value)

如果給定的節存在,則將給定的選項設定為指定的值;否則引發 NoSectionErroroptionvalue 必須是字串;如果不是,則引發 TypeError

write(fileobject, space_around_delimiters=True)

將配置的表示形式寫入指定的檔案物件,該物件必須以文字模式開啟(接受字串)。此表示形式可以被未來的 read() 呼叫解析。如果 space_around_delimiters 為 true,則鍵和值之間的分隔符將被空格包圍。

在 3.14 版更改: 如果這將寫入一個無法被該解析器未來的 read() 呼叫準確解析的表示形式,則會引發 InvalidWriteError。

備註

原始配置檔案中的註釋在寫回配置時不會被保留。什麼被視為註釋,取決於為 comment_prefixinline_comment_prefix 給定的值。

remove_option(section, option)

從指定的 section 中移除指定的 option。如果該節不存在,則引發 NoSectionError。如果要移除的選項存在,則返回 True;否則返回 False

remove_section(section)

從配置中移除指定的 section。如果該節確實存在,則返回 True。否則返回 False

optionxform(option)

將輸入檔案中找到的或由客戶端程式碼傳入的選項名稱 option 轉換為應在內部結構中使用的形式。預設實現返回 option 的小寫版本;子類可以重寫此方法,或者客戶端程式碼可以在例項上設定此名稱的屬性以影響此行為。

你不需要繼承解析器來使用這個方法,你也可以在例項上將它設定為一個接受字串引數並返回字串的函式。例如,將其設定為 str 會使選項名稱區分大小寫

cfgparser = ConfigParser()
cfgparser.optionxform = str

請注意,在讀取配置檔案時,選項名稱周圍的空格會在呼叫 optionxform() 之前被去除。

configparser.UNNAMED_SECTION

一個特殊的對​​象,表示用於引用未命名節的節名稱(參見 未命名節)。

configparser.MAX_INTERPOLATION_DEPTH

raw 引數為 false 時,get() 的遞迴插值的最大深度。這僅在使用預設 interpolation 時相關。

RawConfigParser 物件

class configparser.RawConfigParser(defaults=None, dict_type=dict, allow_no_value=False, *, delimiters=('=', ':'), comment_prefixes=('#', ';'), inline_comment_prefixes=None, strict=True, empty_lines_in_values=True, default_section=configparser.DEFAULTSECT, interpolation=BasicInterpolation(), converters={}, allow_unnamed_section=False)

ConfigParser 的傳統變體。它預設停用插值,並透過其不安全的 add_sectionset 方法以及傳統的 defaults= 關鍵字引數處理,允許非字串的節名、選項名和值。

在 3.2 版更改: 添加了 allow_no_value, delimiters, comment_prefixes, strict, empty_lines_in_values, default_sectioninterpolation

在 3.5 版更改: 添加了 converters 引數。

在 3.8 版更改: 預設的 dict_typedict,因為它現在保留插入順序。

在 3.13 版更改: 添加了 allow_unnamed_section 引數。

備註

請考慮使用 ConfigParser,它會檢查要內部儲存的值的型別。如果你不想要插值,可以使用 ConfigParser(interpolation=None)

add_section(section)

向例項新增一個名為 sectionUNNAMED_SECTION 的節。

如果給定的節已存在,則引發 DuplicateSectionError。如果傳遞了預設節名稱,則引發 ValueError。如果傳遞了 UNNAMED_SECTION 且支援被停用,則引發 UnnamedSectionDisabledError

section 的型別不會被檢查,這允許使用者建立非字串名稱的節區。 這種行為是不受支援的,並可能導致內部錯誤。

在 3.14 版本發生變更: 增加了對 UNNAMED_SECTION 的支援。

set(section, option, value)

如果給定的節區存在,則將給定的選項設定為指定的值;否則會引發 NoSectionError。 雖然可以使用 RawConfigParser(或將 raw 引數設為 true 的 ConfigParser)來內部儲存非字串值,但只有使用字串值才能實現完整的功能(包括插值和輸出到檔案)。

該方法允許使用者在內部為鍵分配非字串值。這種行為是不受支援的,在嘗試寫入檔案或以非原始模式獲取時會導致錯誤。請使用對映協議 API,它不允許進行此類賦值。

異常

exception configparser.Error

所有其他 configparser 異常的基類。

exception configparser.NoSectionError

當找不到指定的節區時引發的異常。

exception configparser.DuplicateSectionError

當使用已存在的節區名稱呼叫 add_section() 時,或在嚴格模式解析器中,當一個節區在單個輸入檔案、字串或字典中出現多次時引發的異常。

在 3.2 版本發生變更: __init__() 添加了可選的 sourcelineno 屬性和形參。

exception configparser.DuplicateOptionError

由嚴格模式解析器在從單個檔案、字串或字典讀取時,如果單個選項出現兩次,則引發異常。這可以捕獲拼寫錯誤和與大小寫敏感性相關的錯誤,例如,一個字典可能有兩個鍵代表同一個不區分大小寫的配置鍵。

exception configparser.NoOptionError

在指定的節區中找不到指定的選項時引發的異常。

exception configparser.InterpolationError

在執行字串插值時出現問題所引發的異常的基類。

exception configparser.InterpolationDepthError

當字串插值因為迭代次數超過 MAX_INTERPOLATION_DEPTH 而無法完成時引發的異常。 InterpolationError 的子類。

exception configparser.InterpolationMissingOptionError

當值中引用的選項不存在時引發的異常。 InterpolationError 的子類。

exception configparser.InterpolationSyntaxError

當進行替換的源文字不符合所需語法時引發的異常。 InterpolationError 的子類。

exception configparser.MissingSectionHeaderError

在嘗試解析一個沒有節區頭的檔案時引發的異常。

exception configparser.ParsingError

在嘗試解析檔案時發生錯誤所引發的異常。

在 3.12 版本發生變更: 移除了 filename 屬性和 __init__() 構造器引數。自 3.2 版起,它們已可透過名稱 source 使用。

exception configparser.MultilineContinuationError

當一個沒有對應值的鍵透過縮排的行進行續行時引發的異常。

在 3.13 版本加入。

exception configparser.UnnamedSectionDisabledError

在未啟用 UNNAMED_SECTION 的情況下嘗試使用它時引發的異常。

在 3.14 版本加入。

exception configparser.InvalidWriteError

當嘗試的 ConfigParser.write() 操作在未來透過 ConfigParser.read() 呼叫時無法被準確解析時引發的異常。

例如:寫入一個以 ConfigParser.SECTCRE 模式開頭的鍵,在讀取時會被解析為節區頭。嘗試寫入此類內容將引發此異常。

在 3.14 版本加入。

腳註