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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4553129/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 16:17:01  来源:igfitidea点击:

When to use os.name, sys.platform, or platform.system?

pythonoperating-systempython-import

提问by ztangent

As far as I know, Python has 3 ways of finding out what operating system is running on:

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

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

Knowing this information is often useful in conditional imports, or using functionality that differs between platforms (e.g. time.clock()on Windows v.s. time.time()on UNIX).

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

My question is, why 3 different ways of doing this? When should one way be used and not another? Which way is the 'best' (most future-proof or least likely to accidentally exclude a particular system which your program can actually run on)?

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

It seems like sys.platformis more specific than os.name, allowing you to distinguish win32from cygwin(as opposed to just nt), and linux2from darwin(as opposed to just posix). But if that's so, that what about the difference between sys.platformand platform.system()?

好像sys.platform是更具体的比os.name,让您区分win32来自cygwin(而不是只nt),并linux2darwin(而不是只posix)。但如果是这样,那sys.platform和之间的区别platform.system()呢?

For example, which is better, this:

例如,哪个更好,这个:

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

or this? :

或这个?:

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

For now I'll be sticking to sys.platform, so this question isn't particularly urgent, but I would be very grateful for some clarification regarding this.

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

回答by Keith

I believe the platform module is probably preferred for new code. The others existed before it. It is an evolution, and the others remain for backwards compatibility.

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

回答by jfs

From sys.platformdocs:

sys.platform文档

  • os.namehas a coarser granularity
  • os.uname()gives system-dependent version information
  • The platformmodule provides detailed checks for the system's identity
  • os.name具有较粗的粒度
  • os.uname()提供与系统相关的版本信息
  • platform模块提供对系统身份的详细检查

Often the "best" future-proof way to test whether some functionality is available is just to try to use it and use a fallback if it fails.

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

what about the difference between sys.platform and platform.system()?

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

platform.system()returns a normalized value that it might get from several sources: os.uname(), sys.platform, vercommand (on Windows).

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

回答by moooeeeep

Dived a bit into the source code.

深入研究了源代码。

The output of sys.platformand os.nameare determined at compile time. platform.system()determines the system type at run time.

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

  • sys.platformis specified as a compiler define during the build configuration.
  • os.namechecks whether certain os specific modules are available (e.g. posix, nt, ...)
  • platform.system()actually runs unameand potentially several other functions to determine the system type at run time.
  • sys.platform在构建配置期间指定为编译器定义。
  • os.name检查是否某些操作系统特定模块可供选择(例如posixnt,...)
  • platform.system()实际运行,uname并可能在运行时确定其他几个函数来确定系统类型。

My suggestion:

我的建议:

  • Use os.nameto check whether it's a posix-compliant system.
  • Use sys.platformto check whether it's a linux, cygwin, darwin, atheos, etc.
  • Use platform.system()if you don't believe the other sources.
  • 使用os.name来检查它是否是一个POSIX兼容的系统。
  • 使用sys.platform来检查它是否是一个linux,cygwin的,达尔文,atheos等。
  • 使用platform.system(),如果你不相信的其他来源。

回答by Abhijit

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

有一线之隔差platform.system()sys.platform,有趣的大多数情况下 platform.system()退化为sys.platform

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

这是消息来源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 = ''

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.

os.uname()

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

Availability: recent flavors of Unix.

回答by hynekcer

It depends on whether you prefer raising exception or trying anything on an untested system and whether your code is so high level or so low level that it can or can't work on a similar untested system (e.g. untested Mac - 'posix' or on embedded ARM systems). More pythonic is to not enumerate all known systems but to test possible relevant properties. (e.g. it is considered important the endianess of the system but unimportant multiprocessing properties.)

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

  • os.name is a sufficient resolution for the correct usage of osmodule. Possible values are 'posix', 'nt', 'os2', 'ce', 'java' or 'riscos' in Python 2.7, while only the 'posix', 'nt' and 'java' are used since Python 3.4.

  • sys.platform is a finer resolution. It is recommended to use if sys.platform.startswith('linux')idiom because "linux2" means a Linux kernel version 2.xx or 3. Older kernels are currently never used. In Python 3.3 are all Linux systems simple 'linux'.

  • 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')惯用语,因为“linux2”表示 Linux 内核版本 2.xx 或 3。较旧的内核目前从未使用过。在 Python 3.3 中,所有 Linux 系统都是简单的“linux”。

I do not know the specifics of "Mac" and "Java" systems and so I can not use the results of very good method platform.system() for branching, but I would use advantages of the platformmodule for messages and error logging.

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