Когда использовать os.name, sys.platform или platform.system? - PullRequest
89 голосов
/ 29 декабря 2010

Насколько я знаю, в Python есть 3 способа узнать, на какой операционной системе выполняется:

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

Знание этой информации часто полезно при условном импорте или при использовании функций, которые различаются для разных платформ (например, time.clock() в Windows v.s. time.time() в UNIX).

Мой вопрос: почему 3 разных способа сделать это? Когда следует использовать один способ, а не другой? Какой путь является «наилучшим» (наиболее вероятным для будущего или наименее вероятным случайным образом исключить конкретную систему, на которой ваша программа может фактически работать)?

Кажется, что sys.platform является более конкретным, чем os.name, что позволяет вам отличать win32 от cygwin (в отличие от nt) и linux2 от darwin (в отличие от просто 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, поэтому этот вопрос не особо актуален, но я был бы очень признателен за разъяснения по этому поводу.

Ответы [ 5 ]

58 голосов
/ 26 июля 2012

Немного погрузился в исходный код.

Выходные данные 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(), хорошо, если вы не Не верьте другим источникам.

19 голосов
/ 13 января 2013

Существует тонкая разница между 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 строк: (sysname, nodename, release, version, machine).Некоторые системы усекают имя узла до 8 символов или до ведущего компонента;лучший способ получить имя хоста - socket.gethostname () или даже socket.gethostbyaddr (socket.gethostname ()).

Availability: recent flavors of Unix.
10 голосов
/ 13 января 2013

Это зависит от того, предпочитаете ли вы вызывать исключение или пробовать что-либо в непроверенной системе, и является ли ваш код настолько высоким или таким низким, что он может или не может работать в аналогичной непроверенной системе (например, непроверенный Mac - 'posix'или на встроенных системах ARM).Более питонным является не перечисление всех известных систем, а проверка возможных соответствующих свойств.(например, считается важным постоянство системы, но несущественные многопроцессорные свойства.)

  • os.name - достаточное разрешение для правильного использования модуля os.Возможные значения: «posix», «nt», «os2», «ce», «java» или «riscos» в Python 2.7, в то время как начиная с 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 для сообщений и регистрации ошибок.

10 голосов
/ 26 июля 2012

Из sys.platform документов :

  • os.name имеет более крупную гранулярность
  • os.uname() предоставляет системно-зависимую информацию о версии
  • Модуль platform предоставляет подробные проверки для идентификации системы

Часто «лучший» способ будущегопроверить, доступна ли какая-либо функция, просто попытаться использовать ее и использовать запасной вариант в случае сбоя.

как насчет различия между sys.platform и platform.system ()?

platform.system() возвращает нормализованное значение, которое может быть получено из нескольких источников: os.uname(), sys.platform, ver (в Windows).

2 голосов
/ 29 декабря 2010

Я считаю, что модуль платформы, вероятно, предпочтительнее для нового кода.Остальные существовали до этого.Это эволюция, а остальные остаются для обратной совместимости.

...