python 格式化输出详解(占位符:%、format、f表达式

python 格式化输出详解(占位符:%、format、f表达式

1.占位符介绍

要实现字符串的拼接,使用占位符是的一种高效、常用的方式。举个例子,下面是不使用占位符的一种写法,直接使用加号拼接字符串

name ="Li hua" age =24print("Hello "+name+", you are "+str(age)+" years old")

换成占位符,可以写成

name ="Li hua" age =24print("Hello %s, you are %d years old"%(name, age))

其中%s%d便是占位符,顾名思义,其作用就是替后面的变量站住这个位置,字符串后面的%是一个特殊的操作符,该操作符会将后面的变量值,替换掉前面字符串中的占位符。对比两种写法,会发现使用占位符可以

  • 将字符串中用到变量集中在一起,方便查找和修改
  • 避免了反复使用引号,导致的引号对应识别困难
  • 能够更直接通顺的看出句子的内容

实际上,占位符的优点还有很多,具体可以在下面的使用中去体会。目前常用的占位符写法有三种

  • %
  • format
  • f表达式

每种方法下,占位符的写法和意思又有不同。下面依次介绍下这三种并给出几个使用示例。

2.%

上文已介绍过,%是一个特殊的操作符,该操作符会将后面的变量值,替换掉前面字符串中的占位符。其详细语法格式如下:

"... %[key][flags][width][.precision][length type]conversion type ..."% values 

其中

%[key][flags][width][.precision][length type]conversion type

是该方法下,占位符详细语法的格式。依次介绍下上面占位符每个符号每个字段的意思

  • %: 必须要有的符号。它标记占位符的开始。
  • key: 选填。映射的键,由带括号的字符序列组成,一般用于后面的values是是字典的场景。
  • flags: 选填。转换标志(Conversion flags), 会影响某些转换类型的结果。
  • width: 选填。最小字段宽度。如果指定为“*”(星号),则实际宽度从值中元组的下一个元素读取,要转换的对象位于最小字段宽度和可选精度之后。
  • precision: 选填。精度,写法为.precision(点+精度)。如果指定为“*”(星号),则实际宽度从值中元组的下一个元素读取,要转换的值位于精度之后。
  • length type: 选填。长度修改器。
  • Conversion type: 必须要有的符号。转换类型,也标记占位符的开始。

下面依次使用一个小示例展示下上面每个字段的用法

Conversion type:由于这个字段是必选字段,所以最先介绍(%写法是固定的,Conversion type则必须要选择一个转换类型)。类型有很多,只介绍三个非常常用的,(更多的建议查阅官方文档:printf-style-string-formatting

Conversion type说明
s字符串(使用str()方法转换任何Python对象)
d十进制整数
f十进制浮点数(小数), 自动保留六位小数。

示例:

print("%s %s %s"%("hello",3,3.1415))print("%s %d %d"%("hello",3,3.1415))print("%s %d %f"%("hello",3,3.1415))print("%s %f %f"%("hello",3,3.1415)) hello 33.1415 hello 33 hello 33.141500 hello 3.0000003.141500

观察上面的示例,不难看出s是一个非常通用的类型,所以很多不讲究的场景,Conversion types是比较可靠的,但是要注意都是字符串类型的。

precision:对于有小数的场景,设置精度是基本操作。其写法为.precision(点+精度)。不设置的话,浮点数默认精度值是6。示例如下:

print('%f'%3.14)print('%.1f'%3.14)print('%.2f'%3.14)#保留多少小数3.140000#默认精度是6 3.13.14

一般来说,%操作符下占位符了解到这里就够了,下面的是比较少用的生僻内容。而且也不实用,复杂的对齐操作推荐使用formatf表达式。

key (不常用):这个选填字段是搭配字典格式的values使用的,示例如下:

print("%(name)s %(age)s"%{"name":"zzz","age":20})print("%(0)s %(1)s"%("zzz",20))#错误的❌❌❌❌---key必须去字典里取值,这样是不行的#输出 zzz 20print("%(0)s %(1)s"%("zzz",20)) TypeError:format requires a mapping #改正print("%(0)s %(1)s"%{"0":"zzz","1":20}) zzz 20

flags :(不常用)该类型可选择的值有:#0-、``、+;这里只介绍其中几种,(更多的建议查阅官方文档:printf-style-string-formatting

flags说明
0数值的转换将被零填充,需搭配width使用(示例见下面的width中的)。
-转化结果左对齐,需搭配width使用(示例见下面的width中的), 该标志符会覆盖0标志符。
``空格, 在带符号的转换产生的正数(或空字符串), 之前留一个空格(方便正负数最后对齐)。
+如果你在格式化数字时使用了 + 标志,那么正数前面会显示 +负数前面会显示 -而且 + 的优先级比“空格标志”更高,会把它顶掉

示例如下

print("% d %+d"%(123,321))print("%d %+d"%(-123,-321))#output123+321-123-321

width:设置字段的最小占位宽度,默认右对齐,内容不够时使用空格填充。

print("%4d,%6d,%10f"%(12,1234,3.14))#用至少4个、6个、10个字符显示一个整数,默认右对齐,不够了就用空格补在左边print("%04d,%06d,%010f"%(12,1234,3.14))#用0来填充不够的位置print("%-4d,%-6d,%-10f"%(12,1234,3.14))#左对齐print("%0-4d,%0-6d,%0-10f"%(12,1234,3.14))#左对齐的时候,0是没有意义的,因为会覆盖0#output12,1234,3.1400000012,001234,003.14000012,1234,3.14000012,1234,3.140000
**Python 的字符串格式化里,没有你需要去“使用”的 length type**它是 C 语言 printf 遗留下来的概念,因此在python中我们可以直接忽略它。

1.什么是 length?(C 语言里的东西)

C 语言 里:

这里的:

这是 C 必须要的,因为 C 是弱类型语言。

2.为社么python不需要length

Python 的整数没有长度限制

Python 的 int任意精度整数。所以:不存在 “int / long / long long” 的区别。也就不需要 length

Python 的格式化是“高层抽象”

都能正常工作。唯一的“历史遗留支持”。Python 的 % 格式化里:

2.type 才是真正重要的东西, **type 决定“怎么解释这个值”, **length 在 Python 中不起作用。

3.format

str.format()是Python2.6开始的新功能,是字符串格式化方法之一,它允许多个替换、值格式化。这个方法允许我们通过位置,格式化连接字符串中的元素。这个方法是一个非常实用且强大的方法。**对于复杂的对齐要求,首选该方法。**其总的语法格式如下:

"... {[field_name][!conversion][:format_spec]} ...".format(arguments)#在 {} 里面可以:#指定 用哪个值(field_name)---必须要的#可选地指定 怎么转换这个值(!conversion)----可选的转换符,能够转换为字符换,ASCⅡ转义等。#可选地指定 怎么格式化显示(:format_spec)#.format(arguments),Python 字符串的方法,用来 把占位符 {} 替换成实际值

3.1 arguments:首先介绍下arguments,其有两种情况:

  • 位置参数(Positional Arguments)-也就是按顺序传递给函数的参数。顺序很重要,如果颠倒就会传错
print("{} {}".format("zhang zhang",668))print("{1} {0} {0} {1}".format("zhang zhang",668))print('{} {} {} {}'.format("zhang zhang",668))#位置参数不够,后便只有两个参数就错了#zhang zhang 668#668 zhang zhang zhang zhang 668#IndexError: Replacement index 2 out of range for positional args tuple
  • 关键字参数(Keyword Arguments)-也就是通过“名字=值”的方式传递参数。顺序不重要
print("{name} {age}".format(name="Li hua", age=24))print("{name} {age} {age} {name}".format("Li hua",24))print("{} {}".format(name="Li hua", age=24))#Li hua 24#KeyError: 'name'#IndexError: Replacement index 0 out of range for positional args tuple
其实位置参数和关键字参数可以混用,但是不推荐混用容易让代码可读性差容易出错(尤其是 {} 没索引时只能用位置参数)

然后介绍下该语法下的占位符格式:

{[field_name][!conversion][:format_spec]}

(1) field_name: 选填。字段名,常使用其基础格式arg_name来指定使用arguments哪一个。对于关键词参数,arg_name必须为其中的关键字,(此时该字段是必填项)比如"{name} {age}".format(name="Li hua", age=24)。对于位置参数,arg_name必须为序号,(此时该字段可不填,不填则默认第一个为0,从前往后依次+1),比如"{0} {1}".format("Li hua", 24)"{} {}".format("Li hua", 24),两者效果一样。

.format() 里,field_name 就是 占位符 {} 里指定的内容,用来告诉 Python 用哪一个参数去填充这个 {}。对于 关键字参数field_name 就是关键字名对于 位置参数field_name 就是参数的序号,也可以省略

该字段完整语法格式为arg_name(.attribute_name | [element_index])*,是在arg_name对应的值为对象、列表或字典时使用,获取其进一步的属性值或者内部值。占位符 {} 不只是可以直接对应参数,还可以“深入访问”参数内部的属性或元素。这里举一个例子:

#也就是说,arg_name可以访问更深层次的属性#例如,最基础的 field_name 就是参数名字或位置号print("{0} {1}".format("Li Hua",24))# 0 → "Li Hua"# 1 → 24#进一步,还可以访问对象属性。如果参数是对象,可以用点号 .属性名 访问对象属性。classPerson:def__init__(self, name, age): self.name = name self.age = age p = Person("Li Hua",24)print("{0.name} {0.age}".format(p))#Li Hua 24#还可以访问列表或者字典元素([element_index]),如果参数是列表、元组或字典,可以用 [] 访问元素。 mylist =["a","b","c"]print("{0[0]} {0[2]}".format(mylist))

conversion:选填。变换,不常用。指定时要用!来开头,指定后会在格式化之前将arguments中对应的值进行类型变换。其有三个值可以指定,分别为

conversion说明
s调用结果对象的str方法进行转换
r调用结果对象的repr方法进行转换
a调用结果对象的ascii方法进行转换

(2)format_spec:选填,格式化具体规范,核心内容,超常用。填写时要用:来开头,填写后,会按照其指定的规则来进行格式化。其详细语法为

在 Python 的 .format()f-string 中,format_spec 用来指定 格式化规则。它总是以 冒号 : 开头,例如:
[[fill]align][sign][#][0][width][grouping_option][.precision][type]

其中所有字段均为选填,下面依次介绍下(其中加粗的为常用),

  • align: 对齐方式,有以下值:

fill: 填充内容,如果指定了宽度,但变量长度不够,会使用该字段值进行填充。设置了fill,后面必须显式设置align。

align说明
<强制左对齐(绝大多数对象默认使用)
>强制右对齐(数字类型默认使用)
=强制将填充内容放在符号(如果有)之后但数字之前,比如输出成+000000120这样的格式。此对齐选项仅对数字类型有效。(当’0’紧接在字段宽度width之前时,它将成为默认值。)
^强制居中对齐
  • sign: 符号展现格式,仅对数字类型有效。有以下值:
sign说明
+正数负数都显示符号,正数用+,负数用-。无论正负,都必须有符号。
-(默认值),仅负数展现符号。默认行为,只给负数加符号
``负数展现符号,正数前面使用一个空格来占位对齐。正数用空格占位,负数用 -
  • grouping_option: 分组选择,有两个选项可选:

width: 最小字段宽度,不设置则字段宽度将始终与填充它的数据长度相同(此时对齐方式align没有意义)。

width ≠ 固定宽度

至少要占这么多字符不够就补够了就不管

0: 当没有设置对齐方式align时, 在宽度字段前面加一个零(‘0’)字符,将等价于填充字符fill0且对齐方式align<

如果你写了 0,但没有写对齐方式Python 会 自动把它理解成:用 0 填充 + 右对齐

#: 复杂生僻,基本不使用,不介绍,有需要的可查阅官方文档(见本部分开头)。

# 的作用主要有两类:进制前缀(二进制 / 八进制 / 十六进制)强制浮点显示小数点
grouping_option说明
,表示使用逗号作为千位分隔符。
_下划线分隔符,复杂生僻,基本不使用,不介绍.
  • type: 类型,决定“怎么显示这个数据”。有很多值,这里只介绍几个常用的:

precision: 精度,指定时要用.来开头,是一个十进制数,指定用’f’和’f’格式化的浮点值在小数点后应该显示多少位,即保留几位小数。

precision 只能写在 . 后面. → 告诉 Python:下面要写“精度”2 → 小数点后保留 2 位f → 浮点数
type说明
s字符串格式。这是字符串的默认类型,可以省略(不填)
d十进制整数
f十进制浮点数(小数), 默认保留六位小数

补充说明1: fill, align只有设置了width才能生效。fill 和 align 的作用对象是“多出来的宽度空间”,如果没有 width,就没有多余空间,所以它们不会生效。简单示例:

#没写的部分 = 使用默认规则,所有规则都是在“width 提供的空间里”起作用print("{:4}{:6},{:10}".format("1","2",3.14))#只有width,没有align-默认右对齐,没有fill-默认填充空格。print("{:4}{:>6}, {:^10}".format("1","2",3.14))#有width,print("{:_<4}{:0>6}, {:^10}".format("1","2",3.14))#有fill。就按照指定的fill填充#output12,3.1412,3.14 1___000002,3.14

4.f 表达式

这是从Python 3.6开始的一个新功能。f表达式(f-string), 又名(formatted string literal), 是前缀为“f”或“f”, 用花括号{}包裹替换字段的字符串文字。其简易格式为: f'{name} is {age} years old'其中花括号{}包裹的是替换字段replacement_field,相当于上面的占位符,但是不同于占位符是先占住位置最后标明变量进行替换,f表达式里的替换字段直接在花括号里面进行变量替换。上面的例子就是用name变量值替换{name}字段,用age变量值替换{age}字段。f表达式详细格式为:

f-string 就是: “在字符串里,用 {} 直接写变量或表达式,Python 会自动替换成结果。”只要字符串前面加了 fF,Python 就会:{} 里面的内容 当成 Python 表达式计算结果再变成字符串,放回原来的位置

其中花括号{}包裹的是替换字段 replacement_field。那么和 .format() / % 的本质区别是?
f'(literal_char | {{ | }} | replacement_field)*'F'(literal_char | {{ | }} | replacement_field)*'


{} 在 f-string 里有 特殊含义,如果你只是想输出一个 **字面量(也就是原来写出来的值,些什么就表示本身,不需要再计算。)的 {}**就必须 转义

以上说明f表达式中的字符串内容,是由任意个literal_char{{}}replacement_field自由组成的。其中literal_char是除花括号{}外的任意字符或空。
f表达式中要表示花括号{}文本,需要进行转义,转义方式为{{, }},

4.1 replacement_field是替换字段,是f表达式的核心。其格式为

{f_expression[=][!conversion][:format_spec]}
  • 替换字段由花括号包裹

f_expression: 必填内容,常规Python表达式,一般要被圆括号包围,只有少数注意事项:1 不允许使用空表达式。

2 lambda和赋值表达式:=必须用显式括号括起来。



在 f-string 的 {} 里:f"{ ... }" 里面只能放“能算出一个值的东西”,不放那些只做动作不产出结果的东西1:数字

2:变量

3:计算

这些都“算得出一个结果”都可以放进 {},但是像x = 10不是算一个值,他是给x赋值的一个命令。但是:=赋值表达式,它在赋值的同时还返回了这个值(x := 10)把10放进x,然后还返回10;大多数表达式 不用括号但有两类表达式 如果不用括号,Python 会“读错”

因为 {} 本身不是一个“完整表达式环境”,而这两种东西语法优先级太特殊,Python 需要你用括号“明确边界”。

:=(赋值表达式,海象运算符)

赋值表达式,意思是一边“赋值”,一边“返回值”

lambda

lambda 是 Python 的匿名函数,也就是“临时函数”,不用给它起名字

3 替换表达式可以包含换行符(例如在三重引号字符串中),但不能包含注释。

4 每个表达式在格式化字符串文本出现的上下文中按从左到右的顺序进行计算。

其完整格式为:

(conditional_expression |* or_expr)(, conditional_expression |,* or_expr)*[,]| yield_expression 

过于复杂,只展示不介绍,详情可查阅官方文档:https://docs.python.org/3/reference/lexical_analysis.html#grammar-token-f-expression

conversion: 选填。转换,指定时要在开头添加!,指定后对表达式求值的结果在格式化之前进行转换。

在表达式后加 ! + 一个字符,对表达式求值的结果在格式化之前进行转换

下方示例中, name = "Ståle"

=: 选填(3.8新版功能), 在表达式后添加等号’=', 可以显示表达式文本及其求值后的值(在调试中很有用),。

在 f-string 的替换字段 {} 内,加上 =,可以打印表达式本身和它的值,主要用于调试,方便看变量名字和对应结果
conversion说明示例输出
s对结果调用str()方法f"His name is {name!s}."'His name is Ståle.'
r对结果调用repr()方法f"His name is {name!r}.""His name is 'Ståle'."
a对结果调用ascii()方法f"His name is {name!a}.""His name is 'St\xe5le'."
  • format_spec: 格式规范, 和本文第二部分format中的format_spec格式规范是一样的。不过这里的可以嵌套使用replacement_field指定其中的值。也就是需要再冒号后写
line ="The output will have the expression text"print(f"{line =}")#变量名+等号,表示显示变量的值。自动打印 “变量名 = 变量的值” width =10#precision = '4f' precision =4 value =12.34567print(f"result: {value:{10}.{4}}")#width 为10, precision精度为4,就是保留小数点后4位print(f"result: {value:{width}.{precision}f}")#{value:{width}.{precision}}#{变量:宽度.精度}#.精度 表示:小数点后保留几位。默认情况下,Python 会四舍五入到指定的精度#在 f-string 里,当你写 {value:宽度.精度} 且 没有指定类型 时,是按浮点数处理,但是实际上更像%g保留的是有效数字的总位数,并且:精度指的是 小数点后显示的位数,会自动四舍五入。#当没有指定类型(比如没有写 :10.4f 而是写 :10.4)时,Python 的行为更像 %g(默认类型是g,没有加字母默认是用%g来格式化浮点数,%g 的聪明之处是:自动去除末尾多余的0,尽量用最简洁的方式显示数字。precision = 4 → %g 会先考虑有效数字最多4位):precision = 有效数字的总位数(整数部分 + 小数部分)。#output line ='The output will have the expression text' result:12.35 result:12.3457

Read more

AI智能客服系统架构深度解析:从技术选型到生产环境实践

今天咱们来聊聊AI智能客服系统怎么从零到一搭建起来,特别是那些让开发者头疼的技术选型和性能问题。这玩意儿听起来高大上,但拆开来看,核心就是三座大山:怎么准确听懂用户想干嘛(意图识别)、怎么记住聊到哪儿了(对话状态管理),以及人一多系统别趴窝(高并发响应)。接下来,我就结合自己的踩坑经验,把这几个点掰开揉碎了讲清楚。 一、技术选型:框架还是自研,这是个问题 选型是第一步,也是最纠结的一步。市面上方案很多,主要分三大流派:用开源框架、用云服务、或者自己从头造轮子。 1. 开源框架代表:Rasa * 优点:开源免费,灵活性极高,所有数据和模型都在自己手里,适合对数据隐私和定制化要求高的场景。它的对话管理(Dialogue Management)模块设计得很清晰。 * 缺点:上手有门槛,需要自己处理NLU(自然语言理解)模型训练、部署和运维。在意图识别准确率上,非常依赖于标注数据的质量和数量。实测下来,在中等复杂度的场景,自训练的模型QPS(每秒查询率)大概在200-300左右,

By Ne0inhk
spring全面详解-最全最详细的spring基本认识和入门使用

spring全面详解-最全最详细的spring基本认识和入门使用

文章目录 * Spring * spring概述 * 1 Spring定义 * 2 Spring核心 * 3 Spring Framework的特点 * 入门案例 * 1 环境要求 * 2 构建工程 * 2.1 构建子工程first-spring * 2.2 入门案例 * 2.3 对象存储 * IoC容器 * 1 控制反转IoC * 2 依赖注入DI * 3 IoC容器实现 * 4 基于XML管理bean * 4.1 环境准备 * 4.2 获取bean方式 * 4.3 基于setter依赖注入 * 4.4 基于构造器依赖注入 * 4.5 特殊值处理注入 * 4.5.

By Ne0inhk
【2025 年最新】 Node.js 环境安装与配置超详细教程(附图解 + 避坑指南)

【2025 年最新】 Node.js 环境安装与配置超详细教程(附图解 + 避坑指南)

Node.js 作为前端开发的核心工具,无论是 Vue、React 等框架开发,还是前端工程化构建,都离不开它。本文将以 2025 年最新版本为例,详细讲解 Node.js 的下载、安装、环境配置全过程,并附带高清图解和常见问题解决方案,确保新手也能一次搞定。 一、Node.js 简介         Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,让 JavaScript 可以运行在服务器端。它包含Node 核心程序和npm(包管理工具),安装 Node.js 时会自动附带 npm,无需单独安装。         2025 年的 Node.js 已更新至 v24.

By Ne0inhk

xxxwww在电商爬虫中的实际应用案例

快速体验 1. 打开 InsCode(快马)平台 https://www.inscode.net 2. 点击'项目生成'按钮,等待项目生成完整后预览效果 输入框内输入如下内容: 构建一个基于xxxwww的电商爬虫系统,能够自动抓取指定电商平台的商品信息(名称、价格、评价等),并将数据清洗后存储到MySQL数据库。要求实现定时任务和反爬虫策略,输出可视化报表。 电商数据爬虫的需求背景 在电商运营和市场竞争分析中,及时获取竞品价格、用户评价等数据至关重要。传统人工收集效率低下,而爬虫技术可以自动化这一过程。最近我用xxxwww技术实现了一个电商爬虫系统,能够定时抓取多个平台商品数据并生成可视化报表,大幅提升了团队的数据获取效率。 系统核心功能设计 整个系统主要分为四个模块,每个模块都针对电商数据特点做了优化: 1. 爬虫调度模块:负责管理爬取任务队列,协调多个平台的爬取节奏 2. 数据抓取模块:使用xxxwww技术实现商品详情页的精准定位和数据提取 3. 数据处理模块:对原始数据进行清洗、去重和格式标准化 4.

By Ne0inhk