Python怎么获取系统已安装的所有字体名称
在 Python 中获取系统当前安装的所有字体名称,最通用且开箱即用的方法是使用 matplotlib.font_manager 模块;如果项目对第三方依赖有严格限制,也可以通过 Python 原生模块结合操作系统接口(如 Windows 注册表或 Linux 的 fc-list 命令)直接读取。本文将介绍这两种核心实现路径,并说明字体文件路径与字体族名称的关键差异与排查方法。
一、获取系统字体名称的核心机制
操作系统中的字体通常以 .ttf、.otf 或 .ttc 等格式的文件保存在固定目录下。但需要注意:字体文件名称(如 simhei.ttf)与字体展示名称/字体族名称(Font Family Name,如 SimHei 或 黑体)并不是同一个概念。我们在图表绘制、界面渲染或文档导出时,通常需要使用的是字体族名称。
因此,获取完整字体名称的基本过程包括四个阶段:定位系统目录、解析字体元数据、提取标准字体族名称,最后进行去重与排序。
二、主流实现方案一:使用 Matplotlib(推荐通用跨平台)
如果当前开发环境中已经安装或允许引入数据可视化库 matplotlib,那么使用其内置的 font_manager 是最简单且最健壮的做法。该模块自带多平台字体探测器,并会自动缓存扫描结果。
1. 快速获取所有字体族名称
下面的示例演示了如何通过 font_manager.fontManager.ttflist 直接提取并去重系统中的所有字体族名称:
import matplotlib.font_manager as fm
# 获取系统中所有注册的字体对象
font_entries = fm.fontManager.ttflist
# 提取字体名称(family name)并进行集合去重
font_names = sorted(list(set(f.name for f in font_entries)))
# 输出前 10 个字体名称作为示例验证
print(f"共发现已安装字体数量: {len(font_names)}")
for name in font_names[:10]:
print(f"- {name}")
示例输出:
共发现已安装字体数量: 182
- Arial
- Calibri
- Comic Sans MS
- Courier New
- Georgia
- Microsoft YaHei
- Segoe UI
- SimHei
- SimSun
- Times New Roman
2. 获取指定字体文件的真实名称
如果手中已有某个具体的字体文件路径,想要知道该文件在 Python 中被识别为什么名称,可以使用 FontProperties:
from matplotlib.font_manager import FontProperties
font_path = "C:/Windows/Fonts/msyh.ttc" # 示例路径
prop = FontProperties(fname=font_path)
print(f"该字体文件的真实名称为: {prop.get_name()}")
# 示例输出: 该字体文件的真实名称为: Microsoft YaHei
三、主流实现方案二:原生轻量方案(无需第三方库)
在轻量级服务、命令行脚本或受限部署环境中,如果不想引入体积较大的 Matplotlib,可以使用操作系统自带的接口或工具。
1. Windows 平台:使用内置 winreg 模块
在 Windows 环境下,操作系统会将所有已安装的字体名称及其关联文件登记在注册表中。Python 自带 winreg 标准库,可以在几毫秒内读出所有字体名称:
import winreg
def get_windows_fonts():
fonts = []
# 系统级字体注册表键路径
reg_path = r"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts"
try:
with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, reg_path) as key:
index = 0
while True:
try:
name, _, _ = winreg.EnumValue(key, index)
# 注册表中的名称常带有后缀如 ' (TrueType)',可选择清洗
clean_name = name.split(" (")[0]
fonts.append(clean_name)
index += 1
except OSError:
break
except Exception as e:
print(f"读取注册表失败: {e}")
return sorted(list(set(fonts)))
win_fonts = get_windows_fonts()
print(f"Windows 系统注册字体数量: {len(win_fonts)}")
for f in win_fonts[:5]:
print(f"- {f}")
2. Linux / macOS 平台:使用系统命令行工具
在 Unix-like 系统中,只要系统安装了 fontconfig 工具链,就可以使用 fc-list 命令列出字体。Python 可以通过 subprocess 模块捕获其输出:
import subprocess
def get_unix_fonts():
try:
# : family 表示仅输出字体族名称
result = subprocess.run(["fc-list", ":", "family"], stdout=subprocess.PIPE, text=True, check=True)
raw_lines = result.stdout.strip().split("\n")
fonts = set()
for line in raw_lines:
# 部分字体可能包含多个语言别名,以逗号分隔
for item in line.split(","):
item_clean = item.strip()
if item_clean:
fonts.add(item_clean)
return sorted(list(fonts))
except (subprocess.SubprocessError, FileNotFoundError):
print("未检测到 fc-list 命令,请确认系统是否安装 fontconfig。")
return []
unix_fonts = get_unix_fonts()
print(f"Unix 系统字体数量: {len(unix_fonts)}")
四、两种做法的关键差异与场景选型
为了在工程实践中做出恰当的技术选型,需要在依赖成本、跨平台表现及名称准确性等维度上进行衡量:
- 如果最终目的是在图表绘制(如 Matplotlib、Seaborn)中使用该字体,请务必使用 Matplotlib 方案,因为只有它返回的名字能确保被绘图引擎无误识别。
- 如果只是在后台批量检测系统环境、打印日志或验证特定字体是否存在,使用原生注册表或命令行方案更加轻快。
五、常见问题与注意事项
-
新安装的字体无法被 Matplotlib 识别:
Matplotlib 在首次运行后会在用户的配置目录下生成字体缓存(例如~/.matplotlib/fontlist-*.json)。如果之后手动在系统中安装了新字体,Matplotlib 不一定会立即重新扫描。
解决方法:在代码中执行fm._load_fontmanager(try_read_cache=False)强制重新构建缓存,或直接删除用户目录下的fontlist-*.json缓存文件。 -
中文字体的中英文名称混用问题:
很多中文字体同时具有中文名和英文名(例如“微软雅黑”对应“Microsoft YaHei”,“黑体”对应“SimHei”)。在部分操作系统和绘图库中,推荐优先使用其标准的英文 Family Name,以避免由于源文件编码问题导致的识别异常。 -
用户级字体与系统级字体路径差异:
现代操作系统(如 Windows 10/11、macOS)允许非管理员用户仅为“当前用户”安装字体(Windows 位于%LOCALAPPDATA%\Microsoft\Windows\Fonts)。如果使用原生读取方案,记得兼顾检查当前用户路径下的字体配置。
六、知识总结
通过上述方法,你可以根据项目的依赖要求和运行环境,灵活选择最适合的方式稳定获取系统中的所有字体名称。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













