Когда использовать os.name, sys.platform или platform.system?

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

  • os.name
  • sys.platform
  • platform.system()

Знание этой информации часто полезно при условном импорте или использовании функциональных возможностей, которые различаются между платформами (например, time.clock() в Windows vs .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, поэтому этот вопрос не является особо срочным, но я был бы очень признателен за некоторые разъяснения относительно этого.

Ответ 1

Окунулся немного в исходный код.

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

Ответ 2

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

Availability: recent flavors of Unix.

Ответ 3

Из sys.platform docs:

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

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

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

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

Ответ 4

Это зависит от того, предпочитаете ли вы вызывать исключение или пробовать что-либо в непроверенной системе, и является ли ваш код настолько высоким или настолько низким, что он может или не может работать в аналогичной непроверенной системе (например, непроверенный 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'), потому что "linux2" означает ядро Linux версии 2.xx или 3. Старые ядра в настоящее время никогда не используются. В Python 3.3 все системы Linux просто "linux".

Я не знаю специфики систем "Mac" и "Java" и поэтому не могу использовать результаты очень хорошего метода platform.system() для ветвления, но я бы использовал преимущества модуля platform для сообщений и ошибок протоколирование.

Ответ 5

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