掌握f-string高级用法:日期、数字与嵌套表达式的实战指南

24 阅读9分钟

免费编程软件「python+pycharm」 链接:pan.quark.cn/s/48a86be2f…

在Python开发中,字符串格式化是高频操作。传统方法如%格式化或str.format()存在可读性差、性能不足等问题。Python 3.6引入的f-string(格式化字符串字面量)通过f"{}"语法,将变量或表达式直接嵌入字符串,配合格式说明符实现高效输出。本文通过真实场景案例,解析f-string在日期处理、数字格式化及嵌套表达式中的核心技巧。

一、日期格式化:从基础到高阶的完整实践

1.1 标准日期时间输出

f-string原生支持datetime对象格式化,无需调用strftime()。通过冒号:后接格式说明符即可控制输出样式:

from datetime import datetime
now = datetime.now()
print(f"当前时间:{now:%Y-%m-%d %H:%M:%S}")  # 输出:2026-01-16 14:30:45

转存失败,建议直接上传图片文件

常用日期格式符:

  • %Y:四位数年份(如2026)
  • %m:两位数月份(01-12)
  • %d:两位数日期(01-31)
  • %H:24小时制小时(00-23)
  • %M:分钟(00-59)
  • %S:秒(00-59)

1.2 本地化日期展示

在国际化应用中,使用%A(星期全名)、%B(月份全名)提升可读性。需配合locale模块设置语言环境:

import locale
locale.setlocale(locale.LC_TIME, 'zh_CN.UTF-8')
formatted_date = f"今天是{now:%A}{now:%B} {now.day}日"
print(formatted_date)  # 输出:今天是星期五,一月 16日

转存失败,建议直接上传图片文件

注意:系统需支持目标语言环境,否则需安装对应语言包。

1.3 时区处理

跨国系统需统一存储UTC时间,展示时转换为用户时区。示例将UTC时间转为上海时间:

from datetime import datetime, timedelta, timezone
utc_now = datetime.now(timezone.utc)
shanghai_time = utc_now.astimezone(timezone(timedelta(hours=8)))
print(f"上海时间:{shanghai_time:%Y-%m-%d %H:%M:%S %z}")  # 输出:2026-01-16 22:30:45 +0800

转存失败,建议直接上传图片文件

关键格式符:

  • %z:UTC偏移量(如+0800)
  • %Z:时区名称(如CST)

1.4 微秒级时间戳

性能监控场景需记录微秒级时间,使用%f占位符:

high_precision_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")
print(f"请求处理耗时:{high_precision_time}")  # 输出:2026-01-16 14:30:45.123456

转存失败,建议直接上传图片文件

若需毫秒精度,可截取前3位:

microsecond_part = datetime.now().strftime("%f")[:3]
formatted_time = f"{datetime.now():%Y-%m-%d %H:%M:%S}.{microsecond_part}"

转存失败,建议直接上传图片文件

二、数字格式化:精准控制输出样式

2.1 浮点数精度控制

保留两位小数并自动四舍五入:

price = 1234.56789
print(f"价格:{price:.2f}")  # 输出:1234.57

转存失败,建议直接上传图片文件

应用场景:财务系统金额显示、科学计算结果输出。

2.2 千分位分隔符

大数值添加逗号分隔提升可读性:

population = 1380000000
print(f"中国人口:{population:,}")  # 输出:1,380,000,000

转存失败,建议直接上传图片文件

结合小数格式化:

revenue = 9876543.21
print(f"营收:${revenue:,.2f}")  # 输出:$9,876,543.21

转存失败,建议直接上传图片文件

2.3 进制转换

快速输出二进制、八进制、十六进制:

num = 42
print(f"二进制:{num:b}")  # 输出:101010
print(f"十六进制:{num:x}")  # 输出:2a
print(f"八进制:{num:o}")  # 输出:52

转存失败,建议直接上传图片文件

进阶技巧:添加前缀标识进制类型:

print(f"0x{num:x}")  # 输出:0x2a
print(f"0b{num:b}")  # 输出:0b101010

转存失败,建议直接上传图片文件

2.4 对齐与填充

控制输出宽度并指定填充字符:

text = "Python"
print(f"|{text:<10}|")  # 左对齐,宽度10,默认空格填充 → |Python    |
print(f"|{text:*>10}|")  # 右对齐,宽度10,*填充 → |****Python|
print(f"|{text:=^10}|")  # 居中对齐,宽度10,=填充 → |==Python==|

转存失败,建议直接上传图片文件

应用场景:表格对齐、日志格式化。

三、嵌套表达式:动态构建复杂字符串

3.1 条件判断

直接在f-string中嵌入三元表达式:

score = 85
print(f"结果:{'及格' if score >= 60 else '不及格'}")  # 输出:及格

转存失败,建议直接上传图片文件

多条件判断:结合函数调用实现复杂逻辑:

def get_status(hour):
    return "营业中" if 9 <= hour <= 21 else "已打烊"

current_hour = 14
print(f"当前状态:{get_status(current_hour)}")  # 输出:营业中

转存失败,建议直接上传图片文件

3.2 函数调用

在f-string中直接调用函数处理数据:

def calculate_discount(price, rate):
    return price * rate

original_price = 100
discount_rate = 0.8
print(f"折后价:{calculate_discount(original_price, discount_rate):.2f}")  # 输出:80.00

转存失败,建议直接上传图片文件

3.3 字典/列表访问

安全访问嵌套数据结构:

data = {
    "user": {
        "name": "Alice",
        "scores": [90, 85, 92]
    }
}
print(f"{data['user']['name']}的最高分:{max(data['user']['scores'])}")  # 输出:Alice的最高分:92

转存失败,建议直接上传图片文件

防御性编程:使用dict.get()避免KeyError

user_data = {"name": "Bob"}
print(f"年龄:{user_data.get('age', '未知')}")  # 输出:年龄:未知

转存失败,建议直接上传图片文件

3.4 方法链调用

连续调用对象方法净化数据:

text = "  Python  "
print(f"清理后:'{text.strip().lower()}'")  # 输出:清理后:'python'

转存失败,建议直接上传图片文件

常见方法链

  • strip()/lstrip()/rstrip():去除空白字符
  • lower()/upper():转换大小写
  • replace():替换子字符串

四、性能优化与最佳实践

4.1 性能对比

测试100万次格式化操作耗时:

import timeit

# f-string
f_string_time = timeit.timeit('name = "Alice"; age = 30; f"{name} is {age} years old."', number=1000000)

# str.format()
format_time = timeit.timeit('name = "Alice"; age = 30; "{} is {} years old.".format(name, age)', number=1000000)

# % 格式化
percent_time = timeit.timeit('name = "Alice"; age = 30; "%s is %d years old." % (name, age)', number=1000000)

print(f"f-string: {f_string_time:.4f}秒")
print(f"str.format(): {format_time:.4f}秒")
print(f"% 格式化: {percent_time:.4f}秒")

转存失败,建议直接上传图片文件

输出结果(示例):

f-string: 0.3210秒
str.format(): 0.5874秒
% 格式化: 0.7421

转存失败,建议直接上传图片文件

结论:f-string性能最优,适合高频格式化场景。

4.2 调试技巧

使用=后缀快速查看变量名与值:

x = 10
y = 20
print(f"{x=}, {y=}, {x+y=}")  # 输出:x=10, y=20, x+y=30

转存失败,建议直接上传图片文件

应用场景:快速定位复杂表达式中的中间变量。

4.3 安全性建议

  • 避免直接拼接用户输入:防止代码注入攻击

    # 危险示例(勿用)
    user_input = "evil_code; import os; os.system('rm -rf /')"
    print(f"用户输入:{user_input}")  # 若f-string支持执行表达式会导致灾难
    

    转存失败,建议直接上传图片文件

    安全做法:仅格式化可信数据,对用户输入进行转义处理。

  • 类型检查:确保格式化对象与说明符匹配

    num = 42
    # print(f"{num:.2f}")  # TypeError: %.2f format requires a number
    print(f"{float(num):.2f}")  # 正确转换类型
    

    转存失败,建议直接上传图片文件

五、常见问题解答

Q2:如何格式化负数?
A:使用:+强制显示正负号,或(空格)为正数留空:

num = -42
print(f"{num:+}")  # 输出:-42
print(f"{abs(num): }")  # 输出: 42(正数前留空格)

转存失败,建议直接上传图片文件

Q3:如何限制字符串长度并截断?
A:使用:.N截断至N个字符:

long_text = "This is a very long string."
print(f"截断后:{long_text:.10}")  # 输出:截断后:This is a ve

转存失败,建议直接上传图片文件

Q4:如何输出花括号本身?
A:使用双花括号转义:

print(f"{{这是一个字面量花括号}}")  # 输出:{这是一个字面量花括号}

转存失败,建议直接上传图片文件

Q5:f-string支持多行吗?
A:支持三引号定义多行字符串:

name = "Alice"
age = 30
multi_line = f"""
姓名:{name}
年龄:{age}
职业:开发者
"""
print(multi_line)

转存失败,建议直接上传图片文件

结语

f-string通过简洁的语法和强大的功能,成为Python字符串格式化的首选方案。从日期时间的灵活处理到数字的精准控制,再到动态表达式的无缝嵌入,掌握这些技巧可显著提升代码效率与可读性。实际开发中,建议结合具体场景选择合适的方法,并遵循性能优化与安全最佳实践,打造健壮的字符串处理逻辑。