2010-12-29 8 views
70

Por lo que yo sé, Python tiene 3 maneras de descubrir qué sistema operativo se ejecuta en:Cuándo usar os.name, sys.platform o platform.system?

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

Conocer esta información es a menudo útil en importaciones condicionales, o que usan una funcionalidad que difiere entre plataformas (por ejemplo, time.clock() en Windows vs time.time() en UNIX).

Mi pregunta es, ¿por qué 3 formas diferentes de hacer esto? ¿Cuándo debería usarse una vía y no otra? ¿De qué manera es el "mejor" (más a prueba de futuro o menos probable que excluya accidentalmente un sistema en particular en el que se puede ejecutar realmente su programa)?

Parece que sys.platform es más específica que os.name, lo que le permite distinguir win32 de cygwin (en lugar de sólo nt), y linux2 de darwin (en lugar de sólo posix). Pero si eso es así, ¿qué pasa con la diferencia entre sys.platform y platform.system()?

Por ejemplo, lo que es mejor, esto:

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

o el presente? :

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

Por ahora voy a estar pegando a sys.platform, por lo que esta cuestión no es particularmente urgente, pero yo estaría muy agradecido por alguna aclaración con respecto a esto.

+11

use 'sys.platform.startswith ('linux')' en lugar de 'sys.platform == 'linux2'' para compatibilidad futura – jfs

Respuesta

2

Creo que el módulo de plataforma es probablemente el preferido para el nuevo código. Los otros existieron antes de eso. Es una evolución, y los demás siguen siendo compatibles con versiones anteriores.

+6

Me pregunto si podemos conseguir que los desarrolladores de Python confirmen esto. Tal vez incluso quien desarrolló el módulo de la plataforma. – ztangent

8

De sys.platform docs:

  • os.name tiene una granularidad más gruesa
  • os.uname() da dependiente del sistema información de la versión
  • El módulo platform proporciona comprobaciones detalladas para la identidad

del sistema A menudo, el " La mejor "forma de prueba de futuro para probar si alguna funcionalidad está disponible es solo para t para usarlo y usar una alternativa si falla.

¿qué ocurre con la diferencia entre sys.platform y platform.system()?

platform.system() devuelve un valor normalizado que podría obtener de varias fuentes: os.uname(), sys.platform, ver de comandos (en Windows).

49

Buceamos un poco en el código fuente.

La salida de sys.platform y os.name se determina en tiempo de compilación. platform.system() determina el tipo de sistema en tiempo de ejecución.

  • sys.platform se especifica como un compilador define durante la configuración de compilación.
  • os.name comprueba si los módulos específicos de ciertos OS son disponibles (por ejemplo posix, nt, ...)
  • platform.system() realmente ejecuta uname y potencialmente varias otras funciones para determinar el tipo de sistema en tiempo de ejecución.

Mi sugerencia, utilice os.name para comprobar si se trata de un sistema compatible con POSIX, usar sys.platform para comprobar si se trata de un Linux, Cygwin, Darwin, atheos, lo que sea, y utilizar platform.system(), bueno, si no creen las otras fuentes.

18

Hay una diferencia delgada línea entre platform.system() y sys.platform y de manera interesante para la mayoría de los casos platform.system() degenera a sys.platform

Esto es lo que la Fuente Python2.7\Lib\Platform.py\system dice

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 = '' 

también por la documentation

os.uname()

Devuelve un 5-tuple que contiene información que identifica el sistema operativo actual. La tupla contiene 5 cadenas: (sysname, nodename, versión, versión, máquina). Algunos sistemas truncan el nombre del nodo a 8 caracteres o al componente principal; una mejor forma de obtener el nombre de host es socket.gethostname() o incluso socket.gethostbyaddr (socket.gethostname()).

Availability: recent flavors of Unix. 
7

Depende de si usted prefiere elevar excepción o de intentar cualquier cosa en un sistema probado y si su código es tan alto nivel o bajo nivel por lo que puede o no puede trabajar en un sistema probado similar (por ejemplo, Mac no probada - 'posix' o en sistemas ARM integrados). Más pythonic es no enumerar todos los sistemas conocidos, sino probar posibles propiedades relevantes. (Por ejemplo, se considera importante la endianess del sistema, pero las propiedades de multiprocesamiento sin importancia.)

  • os.name es una resolución suficiente para el uso correcto de os módulo. Los posibles valores son 'posix', 'nt', 'os2', 'ce' o 'riscos', donde probablemente solo los dos primeros sean más importantes.

  • sys.platform es una resolución más fina. Se recomienda utilizar el idioma if sys.platform.startswith('linux') porque "linux2" significa un kernel de Linux versión 2.xx o 3. Los kernels más antiguos no se usan actualmente. En Python 3.3 todos los sistemas Linux son simples 'linux'.

No sé los detalles de los sistemas de "Java" "Mac" y por lo que no puedo usar los resultados de plataforma muy buena método.system() para la bifurcación, pero utilizaría las ventajas del módulo platform para mensajes y registro de errores.

Cuestiones relacionadas