Python f-字符串使用了一种格式化的迷你语言,与老的.format()函数相同。 在冒号之后是如何格式化数值的简短规范。
>>> word = "Hello"
>>> f"{word:/^20}"
'///////Hello////////'
>>> amt = 12345678
>> f"{amt:20,}"
' 12,345,678'
日期时间可以使用strftime语法。
>>> f"{now:%Y-%m on day %d}"
'2022-04 on day 14'
datetime使用与字符串不同的格式化规范的原因是datetime定义了它自己的__format__方法。任何对象都可以定义自己的格式化小语言。 F-strings 和 .format() 将在一个对象上使用 __format__ 方法,并将正在使用的格式化指令传递给它。
>>> class Confused:
... def __format__(self, fmt):
... return f"What is {fmt}?"
...
>>> c = Confused()
>>> f"{c:xyz12}"
'What is xyz12?'
当然,__format__可以用于比Confused所做的更有用的格式化......
地理上的纬度和经度通常以几种不同的格式呈现。度;或度和分;或度、分和秒。 然后,这些数字可以有不同的小数位数,有时单位用符号表示。
这里是__format__中对这些可能性的实现。 格式字符串以 "d"、"dm "或 "dms "开头,表示基本格式。 小数点的位数可以用".N "来指定。 最后,可以添加符号,可以是普通的,也可以是花哨的,通过添加引号或分钟符号。
import dataclasses, re
@dataclasses.dataclass
class LatLong:
lat: float
long: float
def __format__(self, fmt):
dms, nfmt, opts = re.fullmatch(r"(dm?s?)([.\d]*)([′']?)", fmt).groups()
formatted = []
for num in [self.lat, self.long]:
parts = []
for ms in dms[1:]:
parts.append(str(int(num)))
num = abs((num - int(num)) * 60)
parts.append(format(num, nfmt + "f"))
syms = None
if "'" in opts:
syms = "°'\""
elif "′" in opts:
syms = "°′″"
if opts:
parts = [p + s for p, s in zip(parts, syms)]
formatted.append(" ".join(parts))
joined = ", ".join(formatted)
return joined
>>> where = LatLong(42.359764937, -71.092068768)
>>> print(f"Location: {where:d'}")
Location: 42.359765°, -71.092069°
>>> print(f"Location: {where:d.4}")
Location: 42.3598, -71.0921
>>> print(f"Location: {where:dm'}")
Location: 42° 21.585896', -71° 5.524126'
>>> print(f"Location: {where:dms.4'}")
Location: 42° 21' 35.1538", -71° 5' 31.4476"
>>> print(f"Location: {where:dms.4}")
Location: 42 21 35.1538, -71 5 31.4476
>>> print(f"Location: {where:dms.6′}")
Location: 42° 21′ 35.153773″, -71° 5′ 31.447565″
>>> print("There: {:dms.6′}".format(where))
There: 42° 21′ 35.153773″, -71° 5′ 31.447565″
>>> print(format(where, "dms.6′"))
42° 21′ 35.153773″, -71° 5′ 31.447565″
这个实现没有正确处理错误,但显示了基本的想法。 另外,纬度/长度通常用N/S E/W而不是正负值显示。