Importación condicional de módulos en Python

141

En mi programa quiero importar simplejson o json en función de si el sistema operativo en el que se encuentra el usuario es Windows o Linux. Tomo el nombre del sistema operativo como entrada del usuario. Ahora, ¿es correcto hacer lo siguiente?

osys = raw_input("Press w for windows,l for linux")
if (osys == "w"):
    import json as simplejson
else:
    import simplejson  
Tim
fuente
33
¿Por qué tomas el nombre del sistema operativo como entrada del usuario? Mira en el módulo de la plataforma. docs.python.org/library/platform.html platform.platform() o platform.system()debe hacer lo que necesita, en lugar de que un usuario tenga que ingresar algo cada vez que se ejecuta el código.
Joe Kington el
56
@ S.Lott: ¿en serio? Usted sabe que los votos positivos / negativos deben reflejar la calidad de la pregunta , ¿verdad? Y no si está de acuerdo con algo más en el código del OP.
jalf
2
@jalf: Es una mala pregunta en todos los sentidos, excepto en la gramática. No debe encontrarse como una respuesta principal a ningún tipo de búsqueda.
S.Lott
11
@ S.Lott, no hay nada de malo en querer saber si las importaciones condicionales son pitónicas. Y, obviamente, otros están de acuerdo, ya que tiene más de 50 votos a pesar de sus esfuerzos.
SARose
55
+1 para el concepto que estaba buscando (importar solo si utilizo Win); y otro +1 conceptual para compensar el ridículo voto negativo.
S3DEV

Respuestas:

182

He visto que esta expresión idiomática se usa mucho, por lo que ni siquiera tiene que rastrear el sistema operativo:

try:
    import json
except ImportError:
    import simplejson as json
Matt Williamson
fuente
17
Primero debe intentar importar, simplejson as jsonya que es probable que sea una versión más nueva (más rápida) del jsonmódulo estándar .
Seppo Erviälä
o ujsonpor velocidad
lababidi
59

Para responder la pregunta en su título, pero no el caso particular que proporciona, es perfectamente correcto, toneladas de paquetes hacen esto. Probablemente sea mejor averiguar el sistema operativo usted mismo en lugar de confiar en el usuario; Aquí está PySerial haciéndolo como ejemplo.

serial/__init__.py

import sys

if sys.platform == 'cli':
    from serial.serialcli import Serial
else:
    import os
    # chose an implementation, depending on os
    if os.name == 'nt':  # sys.platform == 'win32':
        from serial.serialwin32 import Serial
    elif os.name == 'posix':
        from serial.serialposix import Serial, PosixPollSerial, VTIMESerial  # noqa
    elif os.name == 'java':
        from serial.serialjava import Serial
    else:
        raise ImportError(
            "Sorry: no implementation for your platform ('{}') available".format(
                os.name
            )
        )

Esto solo debe usarse en casos en los que está asumiendo y necesita una garantía sólida de que ciertas interfaces / características estarán allí: por ejemplo, un 'archivo' llamado /dev/ttyX. En su caso: al tratar con JSON, no hay nada que sea realmente específico del sistema operativo y solo está verificando si el paquete existe o no. En ese caso, solo trypara importarlo, y recurrir con un exceptsi falla:

try:
    import some_specific_json_module as json
except ImportError:
    import json
Nick T
fuente
11
No, es muy incorrecto codificar los nombres del sistema operativo para decidir si está disponible simplejsono no json. Está citando código de importaciones inherentemente específicas del sistema operativo , que es un caso muy diferente. Vea la respuesta de Matt para el enfoque correcto.
Glenn Maynard
16
@Glenn Maynard: Te aplazaría entonces; Nunca he usado el jsonpaquete y estaba tratando de responder la pregunta más general "¿puedes hacer importaciones condicionales de módulos?".
Nick T
7

No es aconsejable usar para enlazar json o simplejson con la plataforma del sistema operativo. simplejson es la versión más nueva y avanzada de json, por lo que deberíamos intentar importarlo primero.

Según la versión de Python, puede probar a continuación la forma de importar json o simplejson

import sys
if sys.version_info > (2, 7):
    import simplejson as json
else:
    import json
Aashutosh jha
fuente