web-dev-qa-db-fra.com

Quand utiliser os.name, sys.platform ou platform.system?

Pour autant que je sache, Python a 3 façons de découvrir sur quel système d'exploitation s'exécute:

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

La connaissance de ces informations est souvent utile dans les importations conditionnelles ou dans l'utilisation de fonctionnalités qui diffèrent selon les plates-formes (par exemple time.clock() sous Windows vs. time.time() sous UNIX).

Ma question est, pourquoi 3 façons différentes de faire cela? Quand faut-il utiliser une façon et non une autre? Quelle est la meilleure solution (la plus évolutive ou la moins susceptible d'exclure accidentellement un système particulier sur lequel votre programme peut réellement s'exécuter)?

Il semble que sys.platform Soit plus spécifique que os.name, Vous permettant de distinguer win32 De cygwin (par opposition à seulement nt), et linux2 de darwin (par opposition à seulement posix). Mais si c'est le cas, qu'en est-il de la différence entre sys.platform Et platform.system()?

Par exemple, ce qui est mieux, ceci:

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

ou ca? :

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

Pour l'instant, je m'en tiendrai à sys.platform, Donc cette question n'est pas particulièrement urgente, mais je serais très reconnaissant pour certaines clarifications à ce sujet.

90
ztangent

Plongé un peu dans le code source.

La sortie de sys.platform Et os.name Est déterminée au moment de la compilation. platform.system() détermine le type de système au moment de l'exécution.

  • sys.platform Est spécifié en tant que compilateur défini lors de la configuration de la construction.
  • os.name Vérifie si certains modules spécifiques au système d'exploitation sont disponibles (par exemple posix, nt, ...)
  • platform.system() exécute réellement uname et potentiellement plusieurs autres fonctions pour déterminer le type de système au moment de l'exécution.

Ma suggestion:

  • Utilisez os.name Pour vérifier s'il s'agit d'un système compatible posix.
  • Utilisez sys.platform Pour vérifier s'il s'agit d'un linux, cygwin, darwin, atheos, etc.
  • Utilisez platform.system() si vous ne croyez pas aux autres sources.
59
moooeeeep

Il y a une mince différence entre platform.system() et sys.platform Et, fait intéressant, dans la plupart des cas, platform.system() dégénère en sys.platform

Voici ce que dit la source 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 = ''

Aussi par documentation

os.uname ()

Renvoie un 5-Tuple contenant des informations identifiant le système d'exploitation actuel. Le tuple contient 5 chaînes: (sysname, nodename, release, version, machine). Certains systèmes tronquent le nom de nœud à 8 caractères ou au composant principal; une meilleure façon d'obtenir le nom d'hôte est socket.gethostname () ou même socket.gethostbyaddr (socket.gethostname ()).

Availability: recent flavors of Unix.
19
Abhijit

De sys.platform Docs :

  • os.name a une granularité plus grossière
  • os.uname() donne des informations sur la version dépendante du système
  • Le module platform fournit des vérifications détaillées de l'identité du système

Souvent, la "meilleure" façon à l'épreuve du temps de tester si certaines fonctionnalités sont disponibles consiste simplement à essayer de les utiliser et à utiliser une solution de secours en cas d'échec.

qu'en est-il de la différence entre sys.platform et platform.system ()?

platform.system() retourne une valeur normalisée qui pourrait provenir de plusieurs sources: os.uname(), sys.platform, ver commande (sur Les fenêtres).

10
jfs

Cela dépend si vous préférez lever l'exception ou essayer quoi que ce soit sur un système non testé et si votre code est à un niveau si élevé ou si bas qu'il peut ou non fonctionner sur un système similaire non testé (par exemple Mac non testé - 'posix' ou sur Embarqué ARM systèmes). Plus Pythonic ne consiste pas à énumérer tous les systèmes connus mais à tester les propriétés pertinentes possibles (par exemple, il est considéré comme important l'endianisme du système mais les propriétés de multiprocessing sans importance.)

  • os.name est une résolution suffisante pour une utilisation correcte du module os. Les valeurs possibles sont 'posix', 'nt', 'os2', 'ce', 'Java' ou 'riscos' dans Python 2.7, tandis que seuls les 'posix', 'nt' et 'Java' est utilisé depuis Python 3.4.

  • sys.platform est une résolution plus fine. Il est recommandé d'utiliser if sys.platform.startswith('linux') idiom car "linux2" signifie un noyau Linux version 2.xx ou 3. Les noyaux plus anciens ne sont actuellement jamais utilisés. Dans Python 3.3 sont tous les systèmes Linux simples 'linux'.

Je ne connais pas les spécificités des systèmes "Mac" et "Java" et je ne peux donc pas utiliser les résultats de la très bonne méthode platform.system () pour le branchement, mais j'utiliserais les avantages du module platform pour messages et journalisation des erreurs.

10
hynekcer

Je crois que le module de plate-forme est probablement préféré pour le nouveau code. Les autres existaient avant lui. C'est une évolution, et les autres restent pour une compatibilité ascendante.

2
Keith