问题:何时使用os.name,sys.platform或platform.system?

据我所知,Python有3种方法来找出运行什么操作系统:

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

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

我的问题是,为什么要使用3种不同的方法?什么时候应该使用一种方法而不是另一种方法?哪种方法是“最佳”的(最好是面向未来的,或者最不可能偶然排除程序可以实际运行的特定系统)?

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

例如,这更好:

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

或这个?:

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

现在,我将继续坚持sys.platform下去,因此这个问题并不是特别紧迫,但我将非常感谢您对此进行的澄清。

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

  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).

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)?

It seems like sys.platform is more specific than os.name, allowing you to distinguish win32 from cygwin (as opposed to just nt), and linux2 from darwin (as opposed to just posix). But if that’s so, that what about the difference between sys.platform and 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.


回答 0

深入研究源代码。

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

  • sys.platform 在构建配置期间被指定为编译器定义。
  • os.name检查是否某些操作系统特定模块可供选择(例如posixnt,…)
  • platform.system()实际运行uname以及可能在运行时确定系统类型的其他几个功能。

我的建议:

  • 使用os.name来检查它是否是一个POSIX兼容的系统。
  • 使用sys.platform来检查它是否是一个linux,cygwin的,达尔文,atheos等。
  • 使用platform.system(),如果你不相信的其他来源。

Dived a bit into the source code.

The output of sys.platform and os.name are determined at compile time. platform.system() determines the system type at run time.

  • sys.platform is specified as a compiler define during the build configuration.
  • os.name checks whether certain os specific modules are available (e.g. posix, nt, …)
  • platform.system() actually runs uname and potentially several other functions to determine the system type at run time.

My suggestion:

  • Use os.name to check whether it’s a posix-compliant system.
  • Use sys.platform to check whether it’s a linux, cygwin, darwin, atheos, etc.
  • Use platform.system() if you don’t believe the other sources.

回答 1

有一线之隔差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 = ''

同样根据文档

os.uname()

返回一个5元组,其中包含标识当前操作系统的信息。元组包含5个字符串:(系统名称,节点名称,发行版,版本,计算机)。某些系统将节点名截断为8个字符或开头部分;获得主机名的更好方法是socket.gethostname()甚至socket.gethostbyaddr(socket.gethostname())。

Availability: recent flavors of Unix.

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.

回答 2

sys.platform文档

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

sys.platform和platform.system()之间的区别如何?

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

From sys.platform docs:

  • os.name has a coarser granularity
  • os.uname() gives system-dependent version information
  • The platform module provides detailed checks for the system’s identity

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()?

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


回答 3

这取决于您是希望在未测试的系统上引发异常还是尝试任何操作,以及您的代码是否如此高级或如此之低,以至于它在类似的未经测试的系统(例如未经测试的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')成语,因为“ linux2”表示Linux内核版本为2.xx或3。目前从未使用过较早的内核。在Python 3.3中,所有Linux系统都是简单的“ Linux”。

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

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.)

  • os.name is a sufficient resolution for the correct usage of os module. 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’.

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 platform module for messages and error logging.


回答 4

我相信平台模块可能是新代码的首选。其他人在此之前存在。这是一个演变,其余的则是为了向后兼容。

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.


声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。