Pour autant que je sache, Python a 3 façons de découvrir sur quel système d'exploitation s'exécute:
os.name
sys.platform
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.
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:
os.name
Pour vérifier s'il s'agit d'un système compatible posix.sys.platform
Pour vérifier s'il s'agit d'un linux, cygwin, darwin, atheos, etc.platform.system()
si vous ne croyez pas aux autres sources.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.
De sys.platform
Docs :
os.name
a une granularité plus grossièreos.uname()
donne des informations sur la version dépendante du systèmeplatform
fournit des vérifications détaillées de l'identité du systèmeSouvent, 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).
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.
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.