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


102

据我所知,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下去,因此这个问题并不是特别紧迫,但我将非常感谢您对此进行的澄清。


15
使用sys.platform.startswith('linux')而不是sys.platform == 'linux2'为了将来的兼容性
jfs 2012年

Answers:


67

深入研究源代码。

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

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

我的建议:

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

2
我做了更多的研究,这里是详细的答案:stackoverflow.com/a/58071295/207661
Shital Shah

20

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

11

sys.platform文档

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

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

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


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

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


os.name可能的返回值是'posix''nt''java'根据Python 3中的文档。另请参阅:平台模块docs。我相信,'riscos'并且'os2'可能是来自的返回值os.name;它们可能是的返回值sys.platform。在Python的3 sys.platform文档似乎并不详尽。
afeique '18

1
@afeique:我更新了我对较新的Python的答案,但那是正确的。请参阅Python 3.3-os.name(当时的最新版本)。仍支持Python 2.7,并且'riscos'是可能的值。
hynekcer

感谢@hynekcer,感谢您为添加Python版本号所做的编辑。对于在Python 3.3之后没有意识到它的更改,我深表歉意。我没有仔细阅读文档的不同版本,而是粗略假设Python 3的行为在os.name各个版本之间是一致的。我也没有仔细检查2.7文档,但是我知道您是正确的。
afeique '18

3

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


7
我想知道是否可以让任何Python开发人员来确认这一点。甚至是开发平台模块的人。
ztangent 2010年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.