Importação condicional de módulos em Python


140

No meu programa, quero importar simplejson ou json com base em se o sistema operacional em que o usuário está é Windows ou Linux. Eu pego o nome do sistema operacional como entrada do usuário. Agora, é correto fazer o seguinte?

osys = raw_input("Press w for windows,l for linux")
if (osys == "w"):
    import json as simplejson
else:
    import simplejson  

33
Por que você está usando o nome do sistema operacional como entrada do usuário? Olhe para o módulo da plataforma. docs.python.org/library/platform.html platform.platform() ou platform.system()deve fazer o que você precisa, em vez de ter que um usuário precisar inserir algo toda vez que o código for executado.
9788 Joe

56
@ S.Lott: sério? Você sabe que os votos positivos / negativos destinam-se a refletir a qualidade da pergunta , certo? E não se você concorda com outra coisa no código do OP.
jalf

2
@ jalf: É uma pergunta ruim em todos os sentidos, exceto na gramática. Não deve ser encontrado como a principal resposta a qualquer tipo de pesquisa.
precisa saber é o seguinte

11
@ S.Lott, não há nada de errado em querer saber se as importações condicionais são pitônicas. E, obviamente, outros concordam, pois tem mais de 50 votos, apesar dos seus esforços.
SARose 30/09/16

5
+1 para o conceito que eu estava procurando (importe apenas se estiver usando o Win); e outro +1 conceitual para compensar o ridículo voto negativo.
S3DEV

Respostas:


182

Eu já vi esse idioma usado muito, então você nem precisa cheirar o SO:

try:
    import json
except ImportError:
    import simplejson as json

17
Você deve primeiro tentar importar simplejson as json, pois é provável que seja uma versão mais nova (mais rápida) do jsonmódulo padrão .
Seppo Erviälä

ou ujsonpara velocidade
lababidi

59

Para responder à pergunta em seu título, mas não no caso específico que você fornece, é perfeitamente correto, toneladas de pacotes fazem isso. Provavelmente é melhor descobrir você mesmo em vez de confiar no usuário; aqui está pySerial fazendo isso como um exemplo.

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
            )
        )

Isso deve ser usado apenas nos casos em que você está assumindo e precisa de uma garantia forte de que certas interfaces / recursos estarão lá: por exemplo, um 'arquivo' chamado /dev/ttyX. No seu caso: lidando com JSON, não há nada que seja realmente específico do sistema operacional e você está apenas verificando se o pacote existe ou não. Nesse caso, apenas trypara importá-lo e retorne com um exceptse falhar:

try:
    import some_specific_json_module as json
except ImportError:
    import json

11
Não, é muito incorreto codificar nomes de SOs para decidir se está disponível simplejsonou não json. Você está citando código de importações inerentemente específicas do SO , que é um caso muito diferente. Veja a resposta de Matt para a abordagem correta.
Glenn Maynard

16
@ Glenn Maynard: Eu te daria em seguida; Eu nunca usei o jsonpacote e estava tentando responder à pergunta mais geral "você pode fazer importações condicionais de módulos"?
Nick T

7

Não é aconselhável usar para vincular json ou simplejson à plataforma do SO. simplejson é a versão mais recente e avançada do json, portanto, devemos tentar importá-lo primeiro.

Baseado na versão python, você pode tentar abaixo o caminho para importar json ou simplejson

import sys
if sys.version_info > (2, 7):
    import simplejson as json
else:
    import json
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.