127

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

  1. os.name
  2. sys.platform
  3. platform.system()

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

我的问题是,为什么有 3 种不同的方式来做到这一点?什么时候应该使用一种方式而不是另一种方式?哪种方式是“最好的”(最面向未来或最不可能意外排除您的程序实际可以运行的特定系统)?

它似乎sys.platform比 更具体os.name,允许您区分(与 just 相对)和win32from (与 just 相对)。但如果是这样,那和之间的区别又如何呢?cygwinntlinux2darwinposixsys.platformplatform.system()

例如,哪个更好,这个:

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

或这个?:

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

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

4

5 回答 5

80

深入研究了源代码。

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

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

我的建议:

  • 用于os.name检查它是否是符合 posix 的系统。
  • 用于sys.platform检查是否是linux、cygwin、darwin、atheos等。
  • platform.system()如果您不相信其他来源,请使用。
于 2012-07-26T17:43:48.613 回答
22

There is a thin line difference between platform.system() and sys.platform and interestingly for most cases platform.system() degenerates to sys.platform

Here is what the Source Python2.7\Lib\Platform.py\system says

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 = ''

Also per the documentation

os.uname()

Return a 5-tuple containing information identifying the current operating system. The tuple contains 5 strings: (sysname, nodename, release, version, machine). Some systems truncate the nodename to 8 characters or to the leading component; a better way to get the hostname is socket.gethostname() or even socket.gethostbyaddr(socket.gethostname()).

Availability: recent flavors of Unix.
于 2013-01-13T05:58:35.307 回答
11

来自sys.platform文档

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

sys.platform 和 platform.system() 之间的区别是什么?

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

于 2012-07-26T15:21:32.453 回答
10

这取决于您是更喜欢引发异常还是在未经测试的系统上尝试任何东西,以及您的代码是否如此高级或如此低级以至于它可以或不能在类似的未经测试的系统上工作(例如未经测试的 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模块的优势来记录消息和错误日志。

于 2013-01-13T11:12:56.713 回答
3

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

于 2010-12-29T10:05:37.753 回答