何时使用 os.name、sys.platform 或 platform.system?

Posted

技术标签:

【中文标题】何时使用 os.name、sys.platform 或 platform.system?【英文标题】:When to use os.name, sys.platform, or platform.system? 【发布时间】:2011-05-31 23:42:46 【问题描述】:

据我所知,Python 有 3 种方法可以找出正在运行的操作系统:

    os.name sys.platform platform.system()

了解这些信息对于条件导入或使用不同平台的功能(例如,Windows 上的 time.clock() 与 UNIX 上的 time.time())通常很有用。

我的问题是,为什么要使用 3 种不同的方法?什么时候应该使用一种方式而不是另一种方式?哪种方式是“最好的”(最具前瞻性或最不可能意外排除您的程序可以实际运行的特定系统)?

似乎sys.platformos.name 更具体,允许您区分win32cygwin(而不是仅仅nt),以及linux2darwin(而不是只是posix)。但如果是这样,那sys.platformplatform.system() 的区别呢?

例如,哪个更好,这个:

import sys
if sys.platform == 'linux2':
    # Do Linux-specific stuff

还是这个? :

import platform
if platform.system() == 'Linux':
    # Do Linux-specific stuff

现在我会坚持sys.platform,所以这个问题不是特别紧急,但我会非常感谢你对此的澄清。

【问题讨论】:

使用 sys.platform.startswith('linux') 代替 sys.platform == 'linux2' 以实现未来兼容性 我这样做:如果 sys.platform == "linux" 或 sys.platform == "linux2": 【参考方案1】:

深入了解源代码。

sys.platformos.name 的输出在编译时确定。 platform.system() 在运行时确定系统类型。

sys.platform 在构建配置期间被指定为编译器定义。 os.name 检查某些特定于操作系统的模块是否可用(例如 posixnt、...) platform.system() 实际运行 uname 并可能运行其他几个函数来确定运行时的系统类型。

我的建议:

使用os.name 来检查它是否是符合posix 的系统。 使用sys.platform查看是否是linux、cygwin、darwin、atheos等 如果您不相信其他来源,请使用 platform.system()

【讨论】:

我做了更多的研究,这里是详细的答案:***.com/a/58071295/207661。【参考方案2】:

platform.system()sys.platform 之间存在细微差别,有趣的是,大多数情况下 platform.system() 退化为 sys.platform

这是消息来源Python2.7\Lib\Platform.py\system 所说的

def system():

    """ Returns the system/OS name, e.g. 'Linux', 'Windows' or 'Java'.

        An empty string is returned if the value cannot be determined.

    """
    return uname()[0]

def uname():
    # Get some infos from the builtin os.uname API...
    try:
        system,node,release,version,machine = os.uname()
    except AttributeError:
        no_os_uname = 1

    if no_os_uname or not filter(None, (system, node, release, version, machine)):
        # Hmm, no there is either no uname or uname has returned
        #'unknowns'... we'll have to poke around the system then.
        if no_os_uname:
            system = sys.platform
            release = ''
            version = ''
            node = _node()
            machine = ''

同样根据documentation

os.uname()

返回一个 5 元组,其中包含标识当前操作系统的信息。元组包含 5 个字符串:(sysname, nodename, 版本、版本、机器)。一些系统将节点名截断为 8 字符或前导组件;一个更好的方法来获得 主机名是 socket.gethostname() 甚至 socket.gethostbyaddr(socket.gethostname()).

Availability: recent flavors of Unix.

【讨论】:

【参考方案3】:

来自sys.platform docs:

os.name 粒度更粗 os.uname() 提供系统相关的版本信息 platform 模块提供对系统身份的详细检查

通常,测试某些功能是否可用的“最佳”面向未来的方法就是尝试使用它并在失败时使用回退。

sys.platform 和 platform.system() 有什么区别?

platform.system() 返回一个标准化值,它可能从多个来源获得:os.uname()sys.platformver 命令(在 Windows 上)。

【讨论】:

【参考方案4】:

这取决于您是更喜欢引发异常还是在未经测试的系统上尝试任何东西,以及您的代码是否如此高级或如此低级以至于它可以或不能在类似的未经测试的系统上工作(例如未经测试的 Mac - 'posix ' 或在嵌入式 ARM 系统上)。更多的 Pythonic 是不枚举所有已知系统,而是测试可能的相关属性。 (例如,系统的字节顺序很重要,但多处理属性并不重要。)

os.name 是正确使用os 模块的足够分辨率。在 Python 2.7 中可能的值是 'posix'、'nt'、'os2'、'ce'、'java' 或 'riscos',而从 Python 3.4 开始只使用 'posix'、'nt' 和 'java'。

sys.platform 是更精细的分辨率。建议使用if sys.platform.startswith('linux') idiom,因为“linux2”表示 Linux 内核版本 2.xx 或 3。目前从不使用较旧的内核。在 Python 3.3 中,所有 Linux 系统都是简单的“linux”。

我不知道“Mac”和“Java”系统的细节,所以我不能使用非常好的方法 platform.system() 的结果进行分支,但我会使用 platform 模块的优势消息和错误记录。

【讨论】:

os.name 根据Python 3 docs,可能的返回值为'posix''nt''java'。另请参阅:platform module docs。我确实相信'riscos''os2' 可能是来自os.name 的返回值;他们可能是return values from sys.platform。 Python 3 sys.platform documentation 似乎并不详尽。 @afeique:我为较新的 Python 更新了答案,但当时是正确的。见Python 3.3 - os.name(当时最新版本)。 Python 2.7 仍然受支持,并且 'riscos' 是一个可能的值。 感谢 @hynekcer,感谢您添加 Python 版本号的编辑。我很抱歉没有意识到它在 Python 3.3 之后发生了变化。我没有仔细阅读文档的不同版本,并粗略地假设os.name 的 Python 3 行为在各个版本之间是一致的。我也没有仔细检查2.7 documentation,但我现在知道你是对的。【参考方案5】:

我相信平台模块可能更适合新代码。其他人在它之前就存在了。这是一个演进,其他的保留是为了向后兼容。

【讨论】:

我想知道我们是否可以让任何 Python 开发人员确认这一点。甚至可能是开发平台模块的人。

以上是关于何时使用 os.name、sys.platform 或 platform.system?的主要内容,如果未能解决你的问题,请参考以下文章

在 64 位 Python 上使用 sys.platform=='win32' 检查是不是安全?

sys模块

Python sys 模块

sys

sys模块

sys