Domanda

Qual è un buon modo per verificare se un pacchetto è installato all'interno di uno script Python? So che è facile dall'interprete, ma devo farlo all'interno di uno script.

Suppongo di poter verificare se sul sistema è stata creata una directory creata durante l'installazione, ma penso che ci sia un modo migliore. Sto cercando di assicurarmi che il pacchetto Skype4Py sia installato e, in caso contrario, lo installerò.

Le mie idee per eseguire il controllo

  • cerca una directory nel tipico percorso di installazione
  • prova a importare il pacchetto e se viene generata un'eccezione, installa il pacchetto
È stato utile?

Soluzione

Se intendi uno script Python, fai qualcosa del genere:

try:
 import mymodule
except ImportError, e:
 pass # module doesn't exist, deal with it.

Altri suggerimenti

Risposta aggiornata

Un modo migliore per farlo è:

import subprocess
import sys

reqs = subprocess.check_output([sys.executable, '-m', 'pip', 'freeze'])
installed_packages = [r.decode().split('==')[0] for r in reqs.split()]

Il risultato:

print(installed_packages)

[
    "Django",
    "six",
    "requests",
]

Controlla se requests è installato:

if 'requests' in installed_packages:
    # Do something

Perché in questo modo? A volte hai collisioni di nomi di app. L'importazione dallo spazio dei nomi dell'app non ti dà il quadro completo di ciò che è installato sul sistema.

Vecchia risposta

Un modo migliore per farlo è:

import pip
installed_packages = pip.get_installed_distributions()

Per pip > = 10.x utilizzare:

from pip._internal.utils.misc import get_installed_distributions

Perché in questo modo? A volte hai collisioni di nomi di app. L'importazione dallo spazio dei nomi dell'app non ti dà il quadro completo di ciò che è installato sul sistema.

Di conseguenza, si ottiene un elenco di pkg_resources.Distribution oggetti. Vedi quanto segue come esempio:

print installed_packages
[
    "Django 1.6.4 (/path-to-your-env/lib/python2.7/site-packages)",
    "six 1.6.1 (/path-to-your-env/lib/python2.7/site-packages)",
    "requests 2.5.0 (/path-to-your-env/lib/python2.7/site-packages)",
]

Crea un elenco:

flat_installed_packages = [package.project_name for package in installed_packages]

[
    "Django",
    "six",
    "requests",
]

Controlla se <=> è installato:

if 'requests' in flat_installed_packages:
    # Do something

A partire da Python 3.3, puoi utilizzare find_spec () metodo

import importlib.util
import sys

# For illustrative purposes.
package_name = 'pandas'

spec = importlib.util.find_spec(package_name)
if spec is None:
    print(package_name +" is not installed")

Se si desidera ottenere il controllo dal terminale, è possibile eseguire

pip3 show package_name

e se non viene restituito nulla, il pacchetto non è installato.

Se forse vuoi automatizzare questo controllo, in modo che, ad esempio, puoi installarlo se mancante, puoi avere quanto segue nel tuo script bash:

pip3 show package_name 1>/dev/null #pip for Python 2
if [ $? == 0 ]; then
   echo "Installed" #Replace with your actions
else
   echo "Not Installed" #Replace with your actions, 'pip3 install --upgrade package_name' ?
fi

Come estensione di questa risposta :

Per Python 2. *, pip show <package_name> eseguirà la stessa attività.

Ad esempio pip show numpy restituirà quanto segue o simili:

Name: numpy
Version: 1.11.1
Summary: NumPy: array processing for numbers, strings, records, and objects.
Home-page: http://www.numpy.org
Author: NumPy Developers
Author-email: numpy-discussion@scipy.org
License: BSD
Location: /home/***/anaconda2/lib/python2.7/site-packages
Requires: 
Required-by: smop, pandas, tables, spectrum, seaborn, patsy, odo, numpy-stl, numba, nfft, netCDF4, MDAnalysis, matplotlib, h5py, GridDataFormats, dynd, datashape, Bottleneck, blaze, astropy

Puoi usare il modulo pkg_resources da setuptools. Ad esempio:

import pkg_resources

package_name = 'cool_package'
try:
    cool_package_dist_info = pkg_resources.get_distribution(package_name)
except pkg_resources.DistributionNotFound:
    print('{} not installed'.format(package_name))
else:
    print(cool_package_dist_info)

Nota che c'è una differenza tra il modulo python e un pacchetto python. Un pacchetto può contenere più moduli e i nomi dei moduli potrebbero non corrispondere al nome del pacchetto.

Vorrei aggiungere alcuni miei pensieri / scoperte a questo argomento. Sto scrivendo uno script che controlla tutti i requisiti per un programma personalizzato. Ci sono molti controlli anche con i moduli Python.

C'è un piccolo problema con

try:
   import ..
except:
   ..

soluzione. Nel mio caso uno dei moduli Python chiamato python-nmap, ma lo importi con import nmap e come vedi i nomi non corrispondono. Pertanto, il test con la soluzione precedente restituisce un risultato False e importa anche il modulo in caso di hit, ma forse non è necessario utilizzare molta memoria per un semplice test / controllo.

L'ho anche trovato

import pip
installed_packages = pip.get_installed_distributions()

installed_packages avrà solo i pacchetti sono stati installati con pip . Sul mio sistema pip freeze ritorna su 40 moduli Python, mentre 1 ha solo nmap, quello che ho installato manualmente (python-nmap).

Un'altra soluzione sotto che la conosco potrebbe non essere pertinente alla domanda , ma penso che sia una buona pratica mantenere la funzione di test separata da quella che esegue il installarlo potrebbe essere utile per alcuni.

La soluzione che ha funzionato per me. Si basa su questa risposta Come verificare se esiste un modulo Python senza importarlo

from imp import find_module

def checkPythonmod(mod):
    try:
        op = find_module(mod)
        return True
    except ImportError:
        return False

NOTA: questa soluzione non riesce a trovare il modulo anche con il nome <=>, devo usare <=> invece (facile da usare) ma in questo caso il modulo non verrà caricato nella memoria di sorta .

Se desideri che il tuo script installi i pacchetti mancanti e continui, potresti fare qualcosa del genere (sull'esempio del modulo 'krbV' nel pacchetto 'python-krbV'):

import pip
import sys

for m, pkg in [('krbV', 'python-krbV')]:
    try:
        setattr(sys.modules[__name__], m, __import__(m))
    except ImportError:
        pip.main(['install', pkg])
        setattr(sys.modules[__name__], m, __import__(m))

Un modo rapido è usare lo strumento da riga di comando python . Digita semplicemente import <your module name> Viene visualizzato un errore se manca il modulo.

$ python
Python 2.7.6 (default, Jun 22 2015, 17:58:13) 
>>> import sys
>>> import jocker
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named jocker
$

Vai all'opzione n. 2. Se viene generato ImportError, il pacchetto non è installato (o non in sys.path).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top