URLhttps://learnscript.net/zh/python/data-types/text-types/format/
    复制链接转到说明  示例

    如何格式化 Python 字符串?format,format_map 方法,Formatter 类介绍

    我被代码海扁署名-非商业-禁演绎
    阅读 17:42·字数 5312·更新 

    本节内容不涉及 Python 旧式 printf 风格的字符串格式化,你可以查看Python 旧式 printf 风格的字符串格式化使用说明一节来了解相关信息。

    字符串格式化中的替换字段

    对于需要进行格式化的字符串,他们通常含有一些替换(格式)字段,替换字段由一个{}及其包含的内容组成,并会被运算结果替换。

    替换字段可能被str类型的formatformat_map方法,格式化字符串,或string模块的Formatter类使用,以用来引用方法的参数或当前可访问的变量等内容。

    如何在格式化字符串时表示大括号自身?

    在对字符串进行格式化时,{}会被解释为替换字段,如果要在字符串中表示{}自身,那么需要将其书写为{{}}

    '{{}}'.format()
    '{}'

    str 类型的 format,format_map 方法

    str类型的formatformat_map方法,提供了格式化字符串的功能,只需要在字符串中书写替换字段,即可引用formatformat_map方法提供的参数。

    format(*args, **kwargs)
    format_map(mapping)

    args 参数

    可变参数args所包含的位置参数将被字符串中的替换字段引用。

    kwargs 参数

    可变参数kwargs所包含的关键字参数将被字符串中的替换字段引用。

    mapping 参数

    参数mapping通常是一个字典对象或通过__getitem__方法提供值的对象,这些对象提供的值将被字符串中的替换字段引用。

    在下面的示例中,我们定义了一个用于格式化的类Data,该类将提供姓名和年龄信息,你需要在字符串中使用{name}{age}来引用他们。

    format.py
    # 一个用于格式化的类
    class Data:
    	def __getitem__(self, key):
    		# 提供姓名和年龄信息
    		if key == 'name':
    			return 'Jack'
    		elif key == 'age':
    			return 12
    
    # 使用 {name} 和 {age} 进行引用 print('{name} 的年龄是 {age}'.format_map(Data()))
    Jack 的年龄是 12

    格式化字符串

    格式化字符串是以fF为前缀的字符串,此类字符串可以包含替换字段,并在其中书写表达式,表达式的计算结果将代替替换字段出现在字符串中。

    a = 1
    b = 2
    F'{a} + {b} = {a + b}'
    '1 + 2 = 3'
    c = {'name': 'Jack', 'age': 12}
    f'{len(c["name"]) > 3} {c["age"] > 12}'
    'True False'

    string 模块的 Formatter 类

    string模块的Formatter类,同样可用于格式化字符串,该类的实例方法formatvformat可实现与str类型的formatformat_map方法类似的效果。

    formatter.format(format_string, /, *args, **kwargs)

    format_string 参数

    参数format_string是需要进行格式化的字符串。

    args 参数

    可变参数args所包含的位置参数将被format_string参数中的替换字段引用。

    kwargs 参数

    可变参数kwargs所包含的关键字参数将被format_string参数中的替换字段引用。

    formatter.vformat(format_string, args, kwargs)

    format_string 参数

    参数format_string是需要进行格式化的字符串。

    args 参数

    参数args是一个序列对象,其包含的元素(项)将被字符串中的替换字段引用。

    kwargs 参数

    参数kwargs是一个映射对象,其包含的元素(项)将被字符串中的替换字段引用。

    import string
    f = string.Formatter()
    f.format('{name} {0}', 12, name='Jack')
    'Jack 12'
    f.vformat('{name} {0}', (12,), {'name': 'Jack'})
    'Jack 12'

    在字符串中引用方法的参数

    对于str类型的formatformat_map方法,以及string模块的Formatter对象的formatvformat方法,字符串中的替换字段{}将按照出现顺序引用format方法中的位置参数,第一个出现的{}引用第一个位置参数,第二个出现的{}引用第二个位置参数,以此类推。

    '{}: "{}"'.format('Jack', 'HELLO')
    'Jack: "HELLO"'

    如果需要在str类型的format方法,以及string模块的Formatter对象的formatvformat方法中引用指定位置的位置参数,那么可以在{}中填写位置参数的索引,0表示引用第一个位置参数。

    替换字段不能引用不存在于 format 方法的位置参数

    对于字符串中的替换字段{},如果其包含的索引所对应的位置参数不存在,那么异常IndexError: Replacement index … out of range for positional args tuple将被引发。

    '{0}: "{1}"'.format('Jack', 'HELLO')
    'Jack: "HELLO"'
    '{1}: "{0}"'.format('Jack', 'HELLO')
    'HELLO: "Jack"'
    '{0}: "{1}, {2}"'.format('Jack', 'HELLO')

    IndexError: Replacement index 2 out of range for positional args tuple

    如果需要在str类型的formatformat_map方法,以及string模块的Formatter对象的formatvformat方法中引用关键字参数,那么可以在{}中填写关键字参数的名称。

    替换字段不能引用不存在于 format,format_map 方法的关键字参数

    如果字符串中的替换字段{}所引用的关键字参数,并不存在于formatformat_map方法,那么异常KeyError: '…'将被引发。

    '{name}: "{word}"'.format(name='Jack', word='HELLO')
    'Jack: "HELLO"'
    '{name}: "{word}"'.format_map({'name': 'Jack', 'word': 'HELLO'})
    'Jack: "HELLO"'
    '{name}: "{word} {other}"'.format_map({'name': 'Jack', 'word': 'HELLO'})

    KeyError: 'other'

    在字符串中引用方法的参数的特性

    对于str类型的formatformat_map方法,以及string模块的Formatter对象的formatvformat方法,在字符串的替换字段中书写.attribute可以访问相关参数的特性(比如,变量,属性等),其中attribute为特性的名称。而书写[key]可以间接调用相关参数的__getitem__方法,这意味着你可以在替换字段中访问列表或字典的值。需要指出,在[key]中书写引号是不可行的,比如[age]不能书写为["age"]['age']

    '{0.real} {0.imag}'.format(12.3-4.56j)
    '12.3 -4.56'
    '{0[0]} {0[1]} {1[name]} {1[age]}'.format((1, 2), {'name': 'jack', 'age': 12})
    '1 2 jack 12'
    '{colors[0]} {colors[1]}'.format(colors=('RED', 'GREEN'))
    'RED GREEN'

    指定用于格式化引用目标的函数

    在正常情况下,字符串中的替换字段所引用的目标对象的__format__方法会被调用,该方法的返回值会代替替换字段。如果希望调用其他函数,那么需要在替换字段中书写!,比如,!s会调用str的构造器(构造函数)来格式化目标对象,!r会调用 Python 的repr函数,!a会调用 Python 的ascii函数。

    Python 对象的 __format__ 方法可能返回其他方法的返回值

    对象的__format__方法可能会直接或间接调用该对象的其他方法(比如__str__),并返回该方法的返回值。

    Python 的 ascii 函数与 repr 函数的区别

    Python 的asciirepr函数的返回值是类似的,只不过在ascii函数的返回值中,非 ASCII 字符将被转换为其对应的编码值。

    在下面的示例中,类Data定义了自己的方法__format____str____repr__,他们将在不同的情况下被调用。

    function.py
    # 一个用于格式化的类
    class Data:
    	def __format__(self, format_spec):
    		return '__format__'
    	def __str__(self):
    		return '__str__'
    	def __repr__(self):
    		return '<对象 "Data">'
    
    # 对象的 __format__ 方法将被调用 print('{}'.format(Data())) # str 的构造器将被调用 print('{!s}'.format(Data())) # repr 函数将被调用 print('{!r}'.format(Data())) # ascii 函数将被调用 print('{0!a}'.format(Data()))
    __format__
    __str__
    <对象 "Data">
    <\u5bf9\u8c61 "Data">

    字符串格式化中的格式规格

    格式规格(Format Specification)被包含在字符串的替换字段中,用于定义如何展示替换字段所对应的值(比如,数字或字符串),其基本的格式如下。

    [<alignment>][sign][z][#][0][width][group][<precision>][type]

    alignment 部分

    alignment部分用于设置对齐方式,具体请参考设置对齐方式一段。

    sign 值

    sign用于设置数字符号的显示方式,具体请参考设置数字的符号显示方式一段。

    z

    z表示将浮点数-0.视为浮点数0.,将复数-0j-0.j视为复数(0+0j),将decimal.Decimal(-0.)视为decimal.Decimal(0.)

    # 值

    #表示为整数显示相关前缀,比如0b(二进制),0o(八进制),0x0X(十六进制),或者强制为浮点数和复数显示小数点。

    0

    0表示自动添加字符0,如果有剩余空间的话。

    width 值

    width表示替换字段占用的最小空间(长度),如果忽略他,则替换字段的空间由其对应的值来决定。

    group 值

    group为数字的分隔符,可以是下划线_或逗号,,具体请参考设置数字的分隔符一段。

    precision 部分

    precision部分通常表示数字的精度,具体请参考设置数字的精度一段。

    type 值

    type用于设置数字或字符串的具体呈现方式,具体请参考设置数字和字符串的具体呈现方式一段。

    '{:}'.format(-0.)
    '-0.0'
    '{:z}'.format(-0.)
    '0.0'
    '{:07}'.format(-1.23)
    '-001.23'
    '{:07}'.format('abc')
    'abc0000'
    '{:#b}'.format(12345)
    '0b11000000111001'
    '{:#}'.format(1+1j)
    '(1.+1.j)'

    在格式化字符串时设置对齐方式

    如果需要在格式化字符串时设置对齐方式,那么应该给出格式规格的alignment部分,其格式如下。需要指出的是,对齐方式仅在可用空间足够时有效,比如,width指定了足够的空间。

    [fill]align

    fill 值

    fill是一个字符,用于填充替换字段的剩余空间,默认为空格。

    align 值

    align表示对齐方式,如果设置为<(大部分情况下的默认值),则采用左对齐,如果设置为>(数字的默认值),则采用右对齐,如果设置为=(仅对数字类型有效,但不包含 complex 类型),则在符号(比如,-+)与数位之间填充fill所表示的字符,如果设置为^,则采用居中对齐(如果无法完成居中,则右边填充的字符会多于左边填充的字符)。

    '{:<10}'.format(1.23)
    '1.23      '
    '{: >10}'.format(1.23)
    '      1.23'
    '{:-^10}'.format(1.23)
    '---1.23---'
    '{:-^11}'.format(1.23)
    '---1.23----'
    '{:0=10}'.format(-1.23)
    '-000001.23'
    '{:=3}'.format(-1.23)
    '-1.23'
    '{:0=10}'.format(-1.23j)

    ValueError: Zero padding is not allowed in complex format specifier

    Python 字符串格式化中的格式规格中的 0

    对于格式规格的alignment部分,如果fill0,那么等同于使用格式规格中的0

    '{:0>5}'.format(1)
    '00001'
    '{:05}'.format(1)
    '00001'

    在格式化字符串时设置数字的符号显示方式

    如果需要在格式化字符串时为数字设置符号的显示方式,那么应该给出格式规格中的signsign仅对数字类型有效,他可以是以下几项之一,+表示正数应显示正号+,负数应显示负号--表示负数应显示负号-,而正数不需要显示符号。 (空格)表示正数前应显示 (空格),负数应显示负号-

    '{:+}'.format(1.23)
    '+1.23'
    '{:+}'.format(-1.23)
    '-1.23'
    '{:-}'.format(+1.23j)
    '1.23j'
    '{:-}'.format(-1.23j)
    '(-0-1.23j)'
    '{: }'.format(1.23)
    ' 1.23'
    '{: }'.format(-1.23)
    '-1.23'

    在格式化字符串时设置数字的分隔符

    如果需要在格式化字符串时为数字设置分隔符,那么应该给出格式规格中的group,他可以是下划线_或逗号,_表示使用_作为最终显示的十进制数字的整数部分的千位分隔符,或使用_作为最终显示的其他进制数字的整数部分的四位分隔符(每四个数位插入一个分隔符)。,表示使用,作为最终显示的十进制数字的整数部分的千位分隔符。

    '{:_}'.format(1234567.89)
    '1_234_567.89'
    '{:_X}'.format(123456789)
    '75B_CD15'
    '{:_b}'.format(123456789)
    '111_0101_1011_1100_1101_0001_0101'
    '{:_}'.format(123456789.12345j)
    '123_456_789.12345j'
    '{:,}'.format(-123456789.12345j)
    '(-0-123,456,789.12345j)'

    在格式化字符串时设置数字的精度

    如果需要在格式化字符串时为数字设置精度,那么应该给出格式规格中的precision部分,其格式如下。如果替换字段所对应的数字的精度超出了限制,那么数字将被舍入。

    .prec

    prec 值

    prec为数字精度,当格式规格中的typefFeE时,精度是指小数点后的位数(将自动补0)。当格式规格中的typegG或被忽略时,精度是指小数点前后的所有位数(不会自动补0)。

    '{:.5f}'.format(1)
    '1.00000'
    '{:.5f}'.format(1.23456789)
    '1.23457'
    '{:.5f}'.format(1.23j)
    '0.00000+1.23000j'
    '{:.5e}'.format(-0xABC123)
    '-1.12561e+07'
    '{:.5g}'.format(1.2)
    '1.2'
    '{:.5g}'.format(1234-123456j)
    '1234-1.2346e+05j'
    '{:.5}'.format(1234-123456j)
    '(1234-1.2346e+05j)'
    '{:.6}'.format(111111.)
    '1.11111e+05'

    格式规格中的 precision 部分可以限制字符串长度

    在字符串的格式化中,虽然格式规格中的precision部分通常用于限制数字的精度,但他同样可以用于限制字符串的长度。

    '{:.3}'.format('Hello')
    'Hel'

    在格式化字符串时设置数字和字符串的具体呈现方式

    在格式化字符串的过程中,通过指定格式规格中的type,你可以为替换字段对应的数字或字符串设置具体的呈现方式。

    对于整数数字,type拥有以下取值,b表示将数字显示为二进制格式,o表示将数字显示为八进制格式,d(默认值)表示将数字显示为十进制格式,x表示将数字显示为十六进制格式,其中字母为小写,X同样表示将数字显示为十六进制格式,但字母为大写。nd类似,但n会根据当前区域设置来决定是否插入数字分隔符。c表示将数字转换为对应的 Unicode 字符。

    '{:b}'.format(123)
    '1111011'
    '{:#x}'.format(0xA1B1C1)
    '0xa1b1c1'
    '{:c}'.format(65)
    'A'

    对于浮点数,复数或类型为decimal.Decimal的数字,type拥有以下取值。需要指出,这些取值同样可用于整数,但在此之前整数(int)会被转换为浮点数(float)。

    e表示将数字显示为科学计数法,此时格式规格中的precision表示小数点后的位数,如果未指定precision,则精度默认为6或尝试显示完整的小数部分(对于decimal.Decimal)。Ee类似,但会采用大写字母。

    f表示将数字显示为定点数,此时格式规格中的precision表示小数点后的位数,如果未指定precision,则精度默认为6或尝试显示完整的小数部分(对于decimal.Decimal)。Ff类似,但会采用大写字母(比如,nan显示为NANinf显示为INF)。

    g表示根据格式规格中的precision(精度为0会被视为1)和数字的值来选择是否使用科学计数法显示数字,数字末尾无意义的0和小数点会被省略(除非使用#),如果未指定precision,则精度默认为6或尝试显示完整的小数部分(对于decimal.Decimal)。Gg类似,但会采用大写字母。

    nd类似,但n会根据当前区域设置来决定是否插入数字分隔符。c表示将数字转换为对应的 Unicode 字符。%(不适用于复数)表示以百分比的形式显示数字,这相当于数字乘以100并被添加了一个百分号%

    如果没有为浮点数或复数指定type,那么相当于使用了g(但会尝试在没有给出精度时显示完整的数字,并尝试去掉复数的实数部分),只不过显示结果中的定点数的小数点后的精度至少为1。如果没有为decimal.Decimal类型的数字指定type,那么相当于使用了gG,具体选择由decimal的上下文决定,你可以通过设置上下文的capitals变量来完成此目标,设置为1(默认值)将采用G,设置为0将采用g,具体形式如下。

    decimal.getcontext().capitals = capitals

    capitals 值

    capitals1(默认值)表示采用大写,为0表示采用小写。

    '{:.3e}'.format(1.2)
    '1.200e+00'
    '{:e}'.format(-12345678j)
    '-0.000000e+00-1.234568e+07j'
    '{:.3f}'.format(1.23j)
    '0.000+1.230j'
    '{:.3g}'.format(1.234j)
    '0+1.23j'
    '{:%}'.format(.23)
    '23.000000%'
    '{:}'.format(1.23456789)
    '1.23456789'
    '{:}'.format(-1.)
    '-1.0'
    '{:}'.format(1.234j)
    '1.234j'
    '{:}'.format(10000000000000000000.)
    '1e+19'

    对于字符串,type可以是s(默认值),通常情况下并不需要书写他,因为这对输出结果没有影响。

    '{:s}'.format('Hello')
    'Hello'

    在格式化字符串时使用嵌套的替换字段

    在格式化字符串时,你可以在一个替换字段中写入另一个替换字段,被写入的替换字段通常会作为格式规格的一部分,比如,作为格式规格中的widthsign

    '{0:{1}}'.format(1.23456, '10')
    '   1.23456'
    '{0:{1}}'.format(1.23456, '.5')
    '1.2346'
    '{0:{c}<{l}}'.format(1.23456, c='+', l=15)
    '1.23456++++++++'

    源码

    src/zh/data_types/text_types/format·codebeatme/python·GitHub