Impor bersyarat modul dengan Python


143

Dalam program saya, saya ingin mengimpor simplejson atau json berdasarkan apakah OS yang digunakan pengguna adalah Windows atau Linux. Saya mengambil nama OS sebagai masukan dari pengguna. Sekarang, apakah benar melakukan hal berikut?

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

33
Mengapa Anda mengambil nama os sebagai masukan dari pengguna? Lihat modul platform. docs.python.org/library/platform.html platform.platform() atau platform.system()harus melakukan apa yang Anda butuhkan, daripada meminta pengguna untuk memasukkan sesuatu setiap kali kode dijalankan.
Joe Kington

57
@ S. Lott: serius? Anda tahu bahwa suara naik / turun dimaksudkan untuk mencerminkan kualitas pertanyaan , bukan? Dan bukan apakah Anda setuju dengan sesuatu yang lain dalam kode OP.
jalf

2
@jalf: Ini pertanyaan yang buruk dalam segala hal kecuali tata bahasa. Ini tidak boleh ditemukan sebagai respons teratas untuk segala jenis penelusuran.
S. Lott

12
@ S.Lott Tidak ada yang salah dengan ingin tahu apakah impor bersyarat itu pythonic. Dan jelas orang lain setuju karena memiliki +50 suara lebih meskipun Anda berusaha.
SARose

Jawaban:


186

Saya telah melihat idiom ini banyak digunakan, jadi Anda bahkan tidak perlu melakukan OS sniffing:

try:
    import json
except ImportError:
    import simplejson as json

18
Anda harus mencoba mengimpor terlebih dahulu simplejson as jsonkarena kemungkinan ini adalah versi jsonmodul standar yang lebih baru (lebih cepat) .
Seppo Erviälä

atau ujsonuntuk kecepatan
lababidi

61

Untuk menjawab pertanyaan dalam judul Anda tetapi bukan kasus tertentu yang Anda berikan, itu benar sekali, banyak paket melakukan ini. Mungkin lebih baik untuk mencari tahu OS sendiri daripada mengandalkan pengguna; inilah pySerial melakukannya sebagai contoh.

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

Ini harus digunakan hanya dalam kasus di mana Anda berasumsi dan membutuhkan jaminan kuat bahwa antarmuka / fitur tertentu akan ada di sana: misalnya 'file' dipanggil /dev/ttyX. Dalam kasus Anda: berurusan dengan JSON, tidak ada yang benar-benar spesifik untuk OS dan Anda hanya memeriksa apakah paket tersebut ada atau tidak. Dalam hal ini, cukup tryuntuk mengimpornya, dan kembali dengan exceptjika gagal:

try:
    import some_specific_json_module as json
except ImportError:
    import json

11
Tidak, sangat tidak tepat untuk nama OS hardcode untuk memutuskan apakah simplejsonatau jsontersedia. Anda mengutip kode dari impor khusus OS , yang merupakan kasus yang sangat berbeda. Lihat jawaban Matt untuk pendekatan yang benar.
Glenn Maynard

17
@ Glenn Maynard: Kalau begitu saya akan tunduk kepada Anda; Saya tidak pernah menggunakan jsonpaket tersebut dan mencoba menjawab pertanyaan yang lebih umum "dapatkah Anda melakukan impor modul bersyarat".
Nick T

7

Tidak disarankan untuk menggunakan json atau simplejson dengan platform OS. simplejson adalah versi json yang lebih baru dan lanjutan jadi kita harus mencoba mengimpornya terlebih dahulu.

Berdasarkan versi python Anda dapat mencoba cara di bawah ini untuk mengimpor json atau simplejson

import sys
if sys.version_info > (2, 7):
    import simplejson as json
else:
    import json
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.