自定义字符串格式化——string formatting
通过format()函数,Python的内建string类可以进行复杂的变量替换以及格式化操作。string模块中定义的Formatter类使得用户可以自己定义内建函数format()的格式化方法。Formatter类定义了几个public函数。
Formatter.format(format_string,*args,**kwargs):主要的API函数。其参数为一个格式字符串、按位置排列的参数以及键值对参数。该函数封装了vformat函数,实际进行格式化的是vformat函数。
vformat(format_string,args,kwargs):该函数才是真正进行格式化工作的函数。它将format_string分解为字符数据,然后进行域替换。该函数会调用下面介绍的几个函数,这些函数有些是可以被Formatter子类重载的。
parse(format_string):解析format_string并返回一个元素为tuple的iterator。tuple的形式为(literal_text, field_name, format_spec, conversion)。该函数被vformat用来分解format_string得到普通文本和替换域。literal_text为原来的文本,不需要进行替换;field_name为需要进行格式化和替换的域;format_spec指定了格式化的形式。
get_field(field_name,args,kwargs):对于parse返回的field_name,将其转换为要进行格式化的对象,返回一个tuple,(obj,used_key)。返回的值used_key和传给get_value()的key参数意义相同。
get_value(key,args,kwargs):获取指定域的值。key可以是一个整数,也可以是一个字符串。数字代表了args里的位置索引,字符串则表示kwargs中的一个指定的key。
check_unused_args(used_args,args,kwargs):根据需要检查没有使用的参数。
format_field(value,format_spec):该函数调用内建函数format()。此函数可以被子类重载。
convert_field(value,conversion):根据指定的转换方式,转换get_field返回的结果。
字符串格式化规则
str.format()和Formatter类使用的字符串格式化规则是一样的。
格式化字符串就是将花括号{}中的内容替换为指定格式的内容。话括弧之外的内容为普通文本,直接复制到输出中。如果要将话括弧放到输出结果中,可以通过重复来转义,如{{,}}分别转义了{和}。
替换域的基本语法如下:
replacement_field::='{field_name [! conversion] [:format_spec]'}
在一般简单使用时,进行替换的域以field_name开头,指定将要被格式化并替换的目标;field_name后面是可选的转换域,以!开头,指定转换类型,一般为r,s或a;再后面是可选的格式化方式,以:开头,具体的格式化规则,后面有详细介绍。
field_name可以是表示位置的整数,也可以是一个表示变量名的字符串。使用数字位置时,数字可以省略,默认从0开始。例如,'My name is {0}',此处field_name就是数字0,0也可以省略;'James Bond is {id}',此处'id'即为一个指示符,将被替换。
conversion取值为s、r或者a,其前缀为!。!s表示对替换目标obj调用str(obj)函数,!r表示repr(obj),!a表示ascii(obj)。
format_spec表示替换结果的显示方式,包括宽度、对齐方式、填充字符、精度等。format_spec和内建函数format的format_spec采用参数相同的格式。format_spec的标准格式如下:
format::=[[fill]align][sign][#][0][width][,][.precision][type]
各项的具体意义如下:
- fill:指定填充字符,默认为空格;
- align:表示对齐方式,取值为<、>、^和=。<、>和^分别表示左对齐、右对齐和居中对齐。=只对数字数字字符串有效,强迫将正负号和数字之间填充指定的填充字符。
- sign:取值为+、-或者空格。仅对数字类型有效。空格表示在正数前是空格,复数前是负号-。
- #:用于int,float,complex和Decimal等类型。不同的类型,其作用不同。对于二进制、八进制和十六进制的整数,在输出的值前面分别加上0b、0o、0x。对于float、complex和Decimal,无论是否有小数部分,在数值后面加上小数点。
- width:用一个十进制数表示结果的最小宽度。默认为目标内容的宽度。
- ,:表示对于数字,每隔三位数字加一个逗号。
- precision:对于浮点型数,指定小数点后面保留数字的位数,即精度。对于非数字类型,指定字符串的最大宽度,即字符的最大个数。
- type:指定数据显示类型,默认为s,即字符串格式。对于数字类型,可以取b、c、d、o、x、X、e、%等。
模板
对应的类为Template。使用Template可以更简单地进行文本替换。它使用基于$的替换方式,而不是类似C语言的%形式。Template的模板规则如下:
$$:转义为单个美元符$;
$identifier:命名一个占位符,用identifier对应的dict类型的键值替换该占位符;
${identifier}:同$identifier,推荐用这种形式,可以避免出错;
任何其他形式出现的$都会抛出ValueError异常。
Template的构造函数只要一个表示模板的字符串为变量,string.Template(template)。其他成员函数如下。
substitute(mapping,**kwargs):用mapping和kwargs中的内容对template中的占位符进行替换,返回一个经过替换的字符串。如果mapping和kwargs中有重复,kwargs中的优先。
safe_substitute(mapping,**kwargs):和substitute的功能相同,不同点在于,如果参数中缺少模板中的占位符,substitute会抛出KeyError异常,safe_substitute不会抛出异常,而是将缺少的占位符和对应的美元符号原封不动的返回。除了占位符外,任何形式形式的$都会返回$,不抛出异常。
工具函数
string模块提供了一个工具函数string.capwords(s,sep=None)。该函数通过调用str.split(sep)将参数s对应字符串分割为几个词,再对每个词调用str.capitalize(),再将这些经过处理的词调用sep.join()组合在一起。
----------------------------------------