Java 程序猿学 python:配置文件

内容纲要

参考资料:https://docs.python.org/3/library/configparser.html

python 配置文件类似 windows 下的 *.ini 文件。一个简单的配置文件如下

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

[bitbucket.org]
User = hg

[topsecret.server.com]
Port = 50022
ForwardX11 = no
  • 配置文件是由 section 组成的,每个 section 都有 section 头,如上例的 [DEFAULT] 就是一个 section 头。section 头后是 key-value 对,k-v 对用等于号(=)或者冒号(:)分隔 key 和 value。
  • 默认情况下,section 名字是大小写敏感的,而 key 则非。key 和 value 前后的空格会被忽略。
  • value 是可以省略的,甚至是分隔符(= 或者 :)也可以没有
  • value 可以跨越多行,只要和第一行保持缩进即可。空行可能被视为多行 value 或者被忽略,取决于 parser 的模式
  • 配置文件可以有注释,注释以 # 或者 ; 开头

示例

[Simple Values]                                              # 简单值
key=value
spaces in keys=allowed                                       # key 里有空格
spaces in values=allowed as well                             # value 里有空格
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       # api 可以返回类型转换后的值 

[Multiline Values]                                           # 多行值
chorus: I'm a lumberjack, and I'm okay
    I sleep all night and I work all day                    # 注意第二行的缩进

[No Values]                                                 # 木有 value
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]                             # section 也可以缩进
        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?     # 注释也可以缩进

写入配置文件

import configparser

config = configparser.ConfigParser()

# 数据结构为 dict
config['DEFAULT'] = {'ServerAliveInterval': '45',
                      'Compression': 'yes',
                      'CompressionLevel': '9'}

# 给 section 添加 k-v
config['bitbucket.org'] = {}
config['bitbucket.org']['User'] = 'hg'

# 另一种添加 k-v 的方法
config['topsecret.server.com'] = {}
topsecret = config['topsecret.server.com']
topsecret['Port'] = '50022'     # mutates the parser
topsecret['ForwardX11'] = 'no'  # same here

config['DEFAULT']['ForwardX11'] = 'yes'

# 写入到文件,后缀名是 ini
with open('example.ini', 'w') as configfile:
   config.write(configfile)

可见,config parser 虽然不是个 dict,但是类似 dict

读取配置文件

import configparser

config = configparser.ConfigParser()
config.sections()
# []
config.read('example.ini')
# ['example.ini']
config.sections()
# ['bitbucket.org', 'topsecret.server.com']
'bitbucket.org' in config
# True
'bytebong.com' in config
# False
config['bitbucket.org']['User']
# 'hg'
config['DEFAULT']['Compression']
# 'yes'
topsecret = config['topsecret.server.com']
topsecret['ForwardX11']
# 'no'
topsecret['Port']
# '50022'
for key in config['bitbucket.org']: print(key)
# user
# compressionlevel
# serveraliveinterval
# compression
# forwardx11
config['bitbucket.org']['ForwardX11']
# 'yes'
  • config.sections() 返回 section 的列表
  • config.read(filename) 读取配置文件

注意

for key in config['bitbucket.org']: print(key) 这行代码不仅打印出了 bitbucket.org 这个 section 的 key(user),还打印了更多的 key(compressionlevel, serveralliveinterval, …),貌似这些 key 都不属于这个 section 啊?

这些 key 实际上是 DEFAULT section 的 key,这个 DEFAULT 这个 section 有些特殊,它定义了所有 section 的默认值

此外,key 是不区分大小写的,从配置文件读出来后自动转换为全部小写的格式

数据类型

config parser 并不会去猜测配置项的数据类型,它总是用字符串来保存配置项。如果需要的话,你得自己做类型转换。

但是,这个类型转换太常用了,config parser 提供了一些方便的 getter 方法来处理整数,浮点数和逻辑值。

尤其是逻辑值,要知道,bool('False') = True,所以要配置一个 False 可不能简单的 some_key=False

所以 config parser 也提供 getboolean,这个方法不区分大小写,并能将 yea/noon/offtrue/false1/0 识别为逻辑值。

备选值

如同 dict 一样,在 sectionget 方法可以提供一个备选值

topsecret.get('Cipher')
# 该 key 不存在,自然也木有 value
topsecret.get('Cipher', '3des-cbc')
# '3des-cbc'

注意

默认值优先于备选值,如果一个 key 在 [DEFAULT] 里设置了默认值,那么即使在 section 的 get 方法里提供备选值,实际返回的也是 [DEFAULT] 里的默认值

如果是在 parser 级别(即非 section 级别)的 get 方法,可以通过 fallback 命名参数来提供一个备选值

config.get('bitbucket.org', 'monster', fallback='No such things as monsters')
# 'No such things as monsters'

getint()getfloat()getboolean() 也支持 fallback 参数

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

插值

一般模版语言都支持插值。配置文件也支持

class configparser.BasicInterpolation

这是个默认实现。它支持在值里包含格式化字符串,引用该 section 或 [DEFAULT] 里定义的其他值,例如

[Paths]
home_dir: /Users
my_dir: %(home_dir)s/lumberjack
my_pictures: %(my_dir)s/Pictures
也可以用其他 section 里的值

[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}

语法

  • 引用当前 section,或者默认 section 的值:%(key)s
  • 引用其他 section 的值:${section_name:key},注意 section 名字是区分大小写的
Java 程序猿学 python:配置文件

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

Scroll to top
粤ICP备2020114259号 粤公网安备44030402004258