字符串
将所有行限制在最多 79 个字符。对于文档字符串或注释等流动的长文本块,行长度应限制在 72 个字符。
愚蠢的一致性是小心眼的产物。风格指南的建议有时并不适用。当有疑问时,运用你的最佳判断。看看其他例子,决定什么看起来最好。不要犹豫,去问吧!
字符串
直接使用引号定义字符串是最常见的方式,定义字符串可以使用单引号、双引号、三重引号。可以在不同类型的引号内部包含其他引号。
当字符串内包含引号时,需要用不同的引号包裹或转义字符。
print("Hello, world!") # 双引号
print('Hello, world!') # 单引号
print("""Hello, world!""") # 三重引号
print('''Hello, world!''') # 三重引号
# 当你想要定义一个包含单引号的字符串时,可以用双引号包裹
print("It's a nice day!") # It's a nice day!
# 反之,当字符串包含双引号时,可以用单引号包裹
print('He said, "Hello!"') # He said, "Hello!"
# 对于多行字符串,三引号允许内部包含单双引号
print("""He said, "It's a nice day!" """) # He said, "It's a nice day!"
# 对于三引号字符串,和上面的包裹案例,也可以使用转义字符来定义
print("""We can use \"\"\" to define string """) # We can use """ to define string
print("He said, \"It's a nice day!\"") # He said, "It's a nice day!"
print("He said, \"Hello!\"") # He said, "Hello!"
print("It\'s a nice day!") # It's a nice day!
# 连续定义多个字符串(中间 有无空格均可)触发字符串字面值合并
string = "1""2" '3'
print(string)
# 输出:
# 123
字符串属于不可变序列对象。
不可变的,这意味着每次修改都会创建新字符串。
序列对象,表示拥有一些共性方法:
- 加法拼接与乘法扩展(大部分序列对象都实现此方法),返回新的字符串
- 索引,返回单个字符
- 切片,返回新的字符串
- 可遍历,每次返回单个字符
- 可使用 in 判断是否包含
- 可使用 len 函数获取长度
s = 'good morning'
# 字符串的拼接
s[:-3] + s[-3:] # good morning
# 字符串的乘法扩展
'-' * 2 # --
# 字符串的索引
s[0] # g
s[-2] # n
# 字符串的切片
s[-3:] # ing
s[:-3] # good morn
s[:] # good morning
# 遍历
for i in s:
print(i,end=' ')
# 输出:
# g o o d m o r n i n g
# in判断
'a' in 'abc' # True
'z' in 'abc' # False
# 使用len函数获取长度
len(s) # 13
# 需要注意避免在循环中使用 `+` 操作符(每次拼接都会创建新字符串)
# 推荐使用列表收集,最后使用 `str.join()` 连接字符串。
# 低效方式
s = ""
for i in range(10000):
s += str(i) # 创建新字符串每次迭代
# 高效方式
parts = []
for i in range(10000):
parts.append(str(i))
s = "".join(parts)
# 进阶方式,流式写入
import io
s = io.StringIO()
for i in range(10000):
s.write(str(i))
s = s.getvalue()
str 函数
str() 函数用于将其他类型的数据转换为字符串类型。这在需要将数字、列表或其他对象作为字符串处理时非常有用。
str 函数签名:str(object='') -> str
参数说明:
object:要转换的对象,默认为空字符串
返回值:
- 返回一个字符串
# 将整数转换为字符串
num = 123
str_num = str(num)
print(str_num) # 输出: '123'
print(type(str_num)) # 输出: <class 'str'>
# 将列表转换为字符串
lst = [1, 2, 3]
str_lst = str(lst)
print(str_lst) # 输出: '[1, 2, 3]'
# 将浮点数转换为字符串
float_num = 3.14
str_float = str(float_num)
print(str_float) # 输出: '3.14'
str() 函数会调用对象的 __str__() 方法来生成字符串表示形式。对于自定义类,可以重写 __str__() 来控制转换结果。
字符串插值
f-string 提供了一种简洁、可读性强的字符串格式化方法。
它在运行时计算表达式,比传统的 % 格式化和 str.format() 更 快、更直观。
而且支持调试表达式、函数调用。
name = "world"
print(f"Hello, {name}!") # Hello, world!
# 嵌入表达式
x = 10
y = 20
result = f"{x} add {y} is {x + y}"
print(result) # 输出: 10 add 20 is 30
# 支持函数、属性、方法的调用
name="jack"
info = f"{name}'s name first letter is {name[0].upper()} , the name length is {len(name)}"
print(info) # 输出: jack's name first letter is J , the name length is 4
Python 3.14 支持模板字符串。
模板字符串为开发者提供了在字符串组合前访问字符串及其插值值的能力。这为 Python 语言带来了原生的灵活字符串处理功能,并支持安全检查、Web 模板、特定领域语言等。
使用起来和 f-string 类似,但是支持 strings 和 interpolations 属性提供对字符串部分和文字中任何插值的访问。
name = "World"
template = t"Hello {name} !"
print(template.interpolations[0].value) # World
print(template.strings[0]) # Hello
print(template.strings[1]) # !
格式说明符
在 str.format() 和 f-strings 中,可以使用格式说明符来控制输出的格式。这对于数字、日期和字符串的精确格式化非常实用。
数字格式化
# 使用 f-strings时,可以直接将值写入,但是推荐先定义变量,代码可读性更好
# 保留两位整数,不足时左侧补零
print(f"{5:02d}") # 输出: 05
# 推荐写法:
value = 5
print(f"{value:02d}")
# 保留两位小数,不足末位补0
pi = 3.14159
print(f"{pi:.2f}") # 输出: 3.14
# 调试表达式,等价于print(f"var={var}")
var = 42
print(f"{var=}") # 输出: var=42
# 对于数字,用逗号或下划线作为组分隔符
data = 123456789
print(f'{data:,}') # 123,456,789
print(f'{data:_}') # 123_456_789
# 表示为百分数,保留两位小数
points = 19
total = 22
print(f'{points/total:.2%}') # 86.36%
# 等价于
print(f'{0.8636363636363636:.2%}') # 86.36%
# 对于数字,格式也支持转化为其他进制
num = 42
print(f"int: {num:d}; hex: {num:x}; oct: {num:o}; bin: {num:b}")
# 输出:int: 42; hex: 2a; oct: 52; bin: 101010
print(f"int: {num:d}; hex: {num:#x}; oct: {num:#o}; bin: {num:#b}")
# 输出:int: 42; hex: 0x2a; oct: 0o52; bin: 0b101010
# 总是显示符号
print(f'{3.14:+f}; {-3.14:+f}')
# 输出:+3.140000; -3.140000
# 对正数显示一个空格
print(f'{3.14: f}; {-3.14: f}')
# 输出: 3.140000; -3.140000
# 只显示负号 -- 等同于 '{:f}; {:f}'
print(f'{3.14:-f}; {-3.14:-f}')
# 输出:3.140000; -3.140000
文本对齐
# 为了便于观察,我在末尾添加了竖线|
hello = "hello|"
name = "bob|"
# 右对齐,表示字符串长度为10,不足时用空格填充
print("{:>10}".format(hello))
print("{:>10}".format(name))
# 输出:
# hello|
# bob|
# 居中对齐,表示字符串长度为10,不足时用空格填充
print("{:^10}".format(hello))
print("{:^10}".format(name))
# 输出:
# hello|
# bob|
# 居左对齐(默认),表示字符串长度为10,不足时用空格填充
print("{:<10}".format(hello))
print("{:<10}".format(name))
# 输出:
# hello|
# bob|
# 左右对齐
class Datebase:
url = '127.0.0.1'
password = '123456'
print(f"""
{"test url:":<20}{Datebase.url:>20}
{"test password:":<20}{Datebase.password:>20}
""")
# 输出:
# test url: 127.0.0.1
# test password: 123456
#
# 带有填充的对齐
# text表示文本,第一处align表示填充字符,第二处align表示对齐方式,16表示长度
for align, text in zip('<^>', ['left', 'center', 'right']):
print(f'{text:{align}{align}16}')
# 输出:
# left<<<<<<<<<<<<
# ^^^^^^center^^^^^
# >>>>>>>>>>right
使用特定类型的专属格式化
import datetime
d = datetime.datetime(2008, 12, 3, 12, 15, 58)
print('{:%Y-%m-%d %H:%M:%S}'.format(d)) # 2008-12-03 12:15:58
# # 2008-12-03 是Python3.0.0的发布日期。
双花括号转义
在字符串格式化中,双花括号 {{ 和 }} 用于转义,表示字面上的花括号字符。这在定义模板字符串时非常有用,特别是大模型提示词等场景,可以先定义模板,稍后再插入参数。
# 定义模板字符串,使用双花括号表示字面上的花括号
template = "你是一个{{role}}助手,请用{{tone}}的语气回答:{{question}}"
# 稍后通过 format() 方法插入参数
prompt = template.format(role="专业", tone="友好", question="什么是Python?")
print(prompt)
# 输出:你是一个专业助手,请用友好的语气回答:什么是Python?
# 也可以使用关键字参数
prompt2 = template.format(
role="教学",
tone="耐心",
question="如何学习编程?"
)
print(prompt2)
# 输出:你是一个教学助手,请用耐心的语气回答:如何学习编程?
# 如果模板中需要包含字面上的花括号,使用双花括号转义
template_with_braces = "变量名:{{name}},值:{{{{value}}}}"
result = template_with_braces.format(name="x", value=42)
print(result)
# 输出:变量名:x,值:{value}
f-string 也支持双花括号转义,但需要注意:f-string 是立即求值的,在定义时就会执行表达式。如果需要在模板中保留花括号供后续格式化,应该使用普通字符串配合 .format() 方法。
# f-string 中使用双花括号转义
name = "Python"
# 在 f-string 中,双花括号会被转义为单个花括号
text = f"语言名称:{{name}}"
print(text)
# 输出:语言名称:{name}
# 注意:f-string 会立即求值,所以这样写会直接替换变量
text2 = f"语言名称:{name}"
print(text2)
# 输出:语言名称:Python
# 如果需要延迟格式化,使用普通字符串模板
template = "语言名称:{{name}}"
# 稍后再格式化
result = template.format(name="Python")
print(result)
# 输出:语言名称:Python