最可靠的方式是使用 platform_system 环境标记在依赖声明中限制平台,它在 pip 解析阶段生效,能阻止不兼容系统安装;需避免运行时检测,因其无法防止无效安装。

setup.py 中用 platform_system 限制安装平台
Python 包的跨平台限制,核心靠 setup.py 或 pyproject.toml 中声明环境标记(environment markers),而不是靠运行时检测。最常用也最可靠的是 platform_system,它在 pip 解析依赖时就生效,能阻止不兼容系统的安装行为。
比如你写了个只支持 Windows 的包,想让 Linux 用户 pip install 时直接失败,就得在依赖项里加条件:
install_requires=[
"pywin32; platform_system == 'Windows'",
"requests"
]
注意:pywin32 只会在 Windows 上被 pip 安装;其他系统会跳过它,但不会报错——除非你把它设为强制依赖又没加标记。
-
platform_system返回值是字符串,常见值:'Linux'、'Windows'、'Darwin'(macOS),大小写敏感 - 不能用
sys.platform或os.name做判断,它们是运行时信息,pip 安装阶段根本没执行你的代码 - 多个条件可用 and/or,例如:
"somepkg; platform_system == 'Linux' and python_version >= '3.8'"
pyproject.toml 里用依赖分组 + 环境标记
现代项目多用 pyproject.toml,限制方式更清晰。不是靠全局开关,而是把平台特定依赖放进可选依赖组,并用环境标记约束:
[project.optional-dependencies] win = ["pywin32; platform_system == 'Windows'"] macos = ["pyobjc; platform_system == 'Darwin'"]
这样用户得显式安装:pip install mypkg[win],否则默认不装这些包。但如果你希望某个包「必须存在且仅限某系统」,就得把它放进 dependencies 并带标记:
[project.dependencies]
"pywin32" = {version = "*", markers = "platform_system == 'Windows'"}
这种写法在 PEP 508 规范下被 pip 3.7+ 完全支持,比旧式 install_requires 更精确。
- 不要写成
markers = "sys_platform == 'win32'"——sys_platform不稳定(比如 WSL 下可能是linux),platform_system才是标准字段 - 如果用了构建后端如
setuptools或hatchling,确保版本够新(setuptools>=64.0.0),否则可能忽略 markers
setup.cfg 不再推荐,但仍有项目在用
老项目若还在用 setup.cfg,也能加环境标记,但语法容易出错:
[options]
install_requires =
requests
pywin32; platform_system == "Windows"
注意这里必须用双引号包裹整个条件表达式,且等号前后不能有空格,否则 setuptools 会解析失败,报错 Invalid environment marker。
- 单引号会被 setuptools 忽略,必须用双引号
- 空格是语法错误源:写成
pywin32 ; platform_system == "Windows"(分号前有空格)会导致 pip 认为这是两个独立依赖 - 这种写法已逐步被弃用,新项目应优先迁移到
pyproject.toml
运行时检测只是补救,不能替代声明式限制
有人会在 __init__.py 里写 if os.name != 'nt': raise OSError("Only Windows supported"),这只能防止导入时报错,不能阻止安装。用户 pip install 成功了,一 import 就崩,体验很差,也不符合 Python 包生态规范。
真正有效的限制,是让 pip 在解析依赖阶段就拒绝安装——靠环境标记实现。运行时检查只适合极少数场景,比如某些 C 扩展在特定内核版本下才会崩溃,但那属于兜底逻辑,不是主控手段。
- CI 测试时务必在非目标系统上验证:比如 Windows-only 包,要在 Linux CI 里跑
pip install . --no-deps看是否跳过条件依赖 - 用户看到的错误信息来自 pip,不是你的代码,所以措辞不可控;唯一能控制的是「不让它走到那一步」
环境标记写错一个字符,比如 Platform_System 或 platform-system,pip 就当普通字符串处理,完全失效。这类问题往往要等到用户反馈才暴露,调试成本高。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











