【Python】一些PEP提案(五):f-string、海象运算符、print 改为函数
PEP 498 – Literal String Interpolation Python,字面字符串插值
也就是传说中的f-string语法,在字符串前添加 f 或 F 前缀,然后在 {} 中放入 Python 表达式:
name = "Alice"
age = 30
# 基本用法
print(f"Hello, {name}! You are {age} years old.")
# 输出:Hello, Alice! You are 30 years old.
# 支持任意表达式
print(f"5 + 3 = {5 + 3}") # 数学运算
# 输出:5 + 3 = 8
print(f"{'uppercase'.upper()}") # 函数调用
# 输出:UPPERCASE
print(f"{age=}") # Python 3.8+ 支持的自解释表达式
# 输出:age=30
在 {} 内使用 : 分隔表达式和格式说明符,支持数字格式化、日期格式化等:
# 数字格式化
pi = 3.1415926
print(f"Pi is approximately {pi:.2f}") # 保留两位小数
# 输出:Pi is approximately 3.14
# 日期格式化
from datetime import datetime
now = datetime.now()
print(f"Today is {now:%Y-%m-%d}") # 按指定格式输出日期
# 输出:Today is 2023-10-01
# 字符串对齐
text = "hello"
print(f"{text:>10}") # 右对齐,总宽度 10
# 输出: hello
需要注意的几件事,第一个是双引号,需要外部为"(双双引号),内部为'(单双引号)
# 正确
print(f"She said: 'Hello, {name}!'")
# 错误(引号冲突)
print(f'She said: "Hello, {name}!"') # 会导致语法错误
如果需要在 f-string 中使用括号,使用额外的括号进行转义:
print(f"{{1, 2, 3}} is a set") # 输出:{1, 2, 3} is a set
通常来说,f-string 的性能是要好于 python 之前的%表示和format表示的,因为 f-string 是在运行时动态计算填充。但是也有例外,代表性的例子就是logging,我们观察如下代码:
import logging
import time
logging.basicConfig(level=logging.INFO) # 仅输出 INFO 及以上级别日志
for i in range(100000):
# 即使日志级别为 INFO,DEBUG 级别的 f-strings 仍会被拼接(但不输出)
logging.debug(f"循环第 {i} 次,当前时间: {time.time()}, 状态: {i % 2 == 0}")
很明显日志的等级为DEBUG,低于配置的INFO等级,不应该被打印出来。但是表达式的内容还是计算了。这种情况就需要用logging自带的format功能了,限于篇幅,不在这里给出。
PEP 572 – Assignment Expressions,表达式内赋值
介绍
海象运算符:=(为什么叫这个名字,因为长得像海象吗???),该特性仅在 Python 3.8+ 支持
我们常常需要声明一些临时变量,用完就扔的那种,放在循环或者判断条件里:
# 传统写法
data = input("Enter something: ")
if len(data) > 5:
print(f"Received: {data}")
虽然data的作用范围是全局,但是显然这里单独一行代码确实很啰嗦。如果使用海象运算符,就可以这么写:
# 使用海象运算符
if (data := input("Enter something: ")) and len(data) > 5:
print(f"Received: {data}")
这就相当于把上面的一行代码塞进来了。注意,这两种写法是完全等效的!也就是说data的作用范围依然是全局:
# 使用海象运算符
if (data := input("Enter something: ")) and len(data) > 5:
print(f"Received: {data}")
print(data)
这样的代码是可以运行的!(可能比较反常识,尤其是对于我这种C++/Java出身的程序员来说,但是我觉得是为了兼容性)
用法
这就有很多花样了。除了上面提到的简化代码,海象运算符的另外一个作用在于减少重复计算:
以下面的代码为例:
# 传统写法
results = [complex_calculation(x) for x in data if complex_calculation(x) > 10]
这里实际上complex_calculation计算了两次(python居然不会自动优化这种结构)
使用海象运算符就会减少一次运算:
# 使用海象运算符
results = [y for x in data if (y := complex_calculation(x)) > 10]
争议
我翻了翻知乎,这玩意从诞生开始就一直存在争议。我认同其中的一种观点:
语言提供了更多特性和选择的机会,但控制权是开发者手里的,就像元类、描述符、dataclass 甚至装饰器等等都是有适用场景的。
鉴于我所在的项目没有用这个特性,我这里就不写更多内容了。
PEP 3105 – Make print a function,print 改为函数
我只想说,python 从 2 到 3 的破坏性改动也不止这一处了,多这一个又何妨。
由于我手里没有 python 2 的环境,这些都是我查的资料。
在 Python 2 中,print 是一个特殊的语法结构(语句),而非普通函数:
# Python 2 的写法
print "Hello, world!" # 无需括号
print x, y # 打印多个值,用逗号分隔
print >> sys.stderr, "Error" # 重定向输出到 stderr
这样带来了很多问题(甚至C的printf都是函数)因此 python3 将其修改为函数。
print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)
更多推荐

所有评论(0)