Errore "Impossibile importare" PyLint - come impostare PYTHONPATH?


165

Sto eseguendo PyLint da Wing IDE su Windows. Ho una sottodirectory (pacchetto) nel mio progetto e all'interno del pacchetto importa un modulo dal livello superiore, ad es.

__init__.py
myapp.py
one.py
subdir\
    __init__.py
    two.py

All'interno two.pyho import onee questo funziona bene in fase di esecuzione, perché la directory di livello superiore (da cui myapp.pyviene eseguita) si trova nel percorso Python. Tuttavia, quando eseguo PyLint su two.py mi dà un errore:

F0401: Unable to import 'one'

Come posso risolvere questo problema?

Risposte:


145

Sono a conoscenza di due opzioni.

Uno, cambia la PYTHONPATHvariabile d'ambiente per includere la directory sopra il tuo modulo.

In alternativa, modifica ~/.pylintrcper includere la directory sopra il tuo modulo, in questo modo:

[MASTER]
init-hook='import sys; sys.path.append("/path/to/root")'

(O in un'altra versione di pylint, l'iniz-hook richiede di cambiare [Generale] in [MASTER])

Entrambe queste opzioni dovrebbero funzionare.

Spero che aiuti.


8
Questo gancio pylint è attualmente il modo migliore in VScode in quanto PYTHONPATH non è ancora supportato per l'uso di linter incorporato.
Danny Staple,

2
Ho lo stesso problema con MacVim con sintetico. Come posso configurare prosector per correggere l'errore di importazione?
Laurent,

Post di blog correlati con qualche dettaglio in più.
Christian Long,

~/.pylintrcha funzionato per me su OSX, l'altro non ha funzionato
Miquel il

Non sono sicuro del perché questa non sia la risposta accettata - anche, vale la pena menzionare per coloro che inciampano su questo, che devi fare in export PYTHONPATHmodo che pylintlo vedano (almeno, in bash / zsh)
Marco Massenzio

43

La soluzione per modificare il percorso init-hookè buona, ma non mi piace il fatto che ho dovuto aggiungere un percorso assoluto lì, di conseguenza non posso condividere questo file pylintrc tra gli sviluppatori del progetto. Questa soluzione che utilizza il percorso relativo al file pylintrc funziona meglio per me:

[MASTER]
init-hook="from pylint.config import find_pylintrc; import os, sys; sys.path.append(os.path.dirname(find_pylintrc()))"

Si noti che pylint.config.PYLINTRCesiste anche e ha lo stesso valore di find_pylintrc().


1
Confermando che questo ha davvero fornito la soluzione per gli errori di pylint E0611 ed E0401. Per utenti VSCode: è importante che la cartella aperta sia la "cartella radice di Python" e che il .pylintrc sia in quella cartella.
np8,

inoltre, assicurarsi che nessuno dei nomi di directory del modulo inizi con .(punto).
Saw-mon e Natalie il

2
se vuoi aggiungere una sottocartella specifica (es. app) puoi usarefrom pylint.config import find_pylintrc; import os, sys; sys.path.append(os.path.join(os.path.dirname(find_pylintrc()), 'app'))
chachan il

27

1) sys.path è un elenco.

2) Il problema è che a volte sys.path non è virtualenv.path e vuoi usare pylint nel tuo virtualenv

3) Quindi, come detto, usa init-hook (presta attenzione in 'e "l'analisi del pylint è rigorosa)

[Master]
init-hook='sys.path = ["/path/myapps/bin/", "/path/to/myapps/lib/python3.3/site-packages/", ... many paths here])'

o

[Master]
init-hook='sys.path = list(); sys.path.append("/path/to/foo")'

.. e

pylint --rcfile /path/to/pylintrc /path/to/module.py

8
Mi è sembrato di aver risolto questo problema installando pylintnel mio virtualenv secondo questo consiglio: plaidzooks.tumblr.com/post/36813101879
Matt

3
Funziona benissimo e dovrebbe essere la risposta migliore. Se non hai un .pylintrc impostato, assicurati di fare un rapido pylint --generate-rcfile > .pylintrcnella cartella home.
reka18,

26

Il problema può essere risolto configurando il percorso pylint in venv: $ cat .vscode / settings.json

{
    "python.pythonPath": "venv/bin/python",
    "python.linting.pylintPath": "venv/bin/pylint"
}

2
Per Windows è { "python.pythonPath": "${workspaceFolder}\\.venv\\Scripts\\python.exe" "python.linting.pylintPath": "${workspaceFolder}\\.venv\\Scripts\\pylint.exe" } solo per completezza.
Roy2511,

La domanda non richiede questo editor.
Ivailo Bardarov,

VSCode ora mostra questo messaggio: The setting "python.pythonPath" defined in your settings.json is now deprecated. se cancello la python.pythonPathlinea sembra comunque funzionare.
Jesse Aldridge il

23

Hai un __init__.pyfile vuoto in entrambe le directory per far sapere a Python che le directory sono moduli?

Lo schema di base quando non si esegue all'interno della cartella (cioè forse da Pylint, anche se non l'ho usato) è:

topdir\
  __init__.py
  functions_etc.py
  subdir\
    __init__.py
    other_functions.py

Questo è il modo in cui l'interprete python è a conoscenza del modulo senza riferimento alla directory corrente, quindi se pylint è in esecuzione dal suo percorso assoluto sarà in grado di accedere functions_etc.pycome topdir.functions_etco topdir.subdir.other_functions, purché topdirsia sul PYTHONPATH.

AGGIORNAMENTO: Se il problema non è il __init__.pyfile, forse prova a copiare o spostare il tuo modulo c:\Python26\Lib\site-packages- questo è un posto comune dove mettere pacchetti aggiuntivi e sarà sicuramente sul tuo pythonpath. Se sai come fare i collegamenti simbolici di Windows o l'equivalente (io no!), Potresti invece farlo. Ci sono molte altre opzioni qui: http://docs.python.org/install/index.html , inclusa l'opzione di aggiungere sys.path con la directory a livello di utente del tuo codice di sviluppo, ma in pratica di solito collego simbolicamente la mia directory di sviluppo locale in pacchetti del sito - copiarlo ha lo stesso effetto.


1
Sì, ho __init__.pyin entrambe le directory. Penso che il problema sia che la directory principale NON è in PYTHONPATH quando PyLint è in esecuzione e non sono sicuro di come risolverlo.
EMP,

Il collegamento simbolico è una buona idea, ma è supportato solo da Windows Vista in poi e sto eseguendo XP. Suppongo che potrei provare a collegarlo duramente ...
EMP,

re hardlinking: No, è meglio non farlo. Ci ho giocato e, anche se sicuramente funziona (in un certo senso), non funzionerà come previsto.
Shylent,

I link simbolici non sono una buona idea. Questo risolve solo il problema sul tuo computer - quando qualcun altro controlla il progetto, verrà risolto per loro.
Jonathan Hartley,

12

risposta generale a questa domanda che ho trovato in questa pagina PER FAVORE NON APERTO, IL SITO È ERRATO

crea .pylintrce aggiungi

[MASTER]
init-hook="from pylint.config import find_pylintrc;
import os, sys; sys.path.append(os.path.dirname(find_pylintrc()))"

5

Non so come funziona con WingIDE, ma per l'utilizzo di PyLint con Geany, ho impostato il comando esterno su:

PYTHONPATH=${PYTHONPATH}:$(dirname %d) pylint --output-format=parseable --reports=n "%f"

dove% f è il nome file e% d è il percorso. Potrebbe essere utile per qualcuno :)


4

Ho dovuto aggiornare la PYTHONPATHvariabile di sistema per aggiungere il mio percorso di App Engine. Nel mio caso ho dovuto solo modificare il mio ~/.bashrcfile e aggiungere la seguente riga:

export PYTHONPATH=$PYTHONPATH:/path/to/google_appengine_folder

In effetti, ho provato a impostare il init-hookprimo ma questo non ha risolto il problema in modo coerente attraverso la mia base di codice (non so perché). Una volta aggiunto al percorso del sistema (probabilmente una buona idea in generale) i miei problemi sono scomparsi.


3

Una soluzione alternativa che ho appena scoperto è in realtà eseguire PyLint per l'intero pacchetto, anziché un singolo file. In qualche modo, riesce a trovare il modulo importato allora.


Sembra fantastico; Come?
Cees Timmerman,

1
@CeesTimmerman Esegui pylint ... dirdalla cartella principale. Ciò richiede __init__.pydi essere presente in ogni sottocartella con i .pyfile.
yugr

3

Provare

if __name__ == '__main__':
    from [whatever the name of your package is] import one
else:
    import one

Si noti che in Python 3, la sintassi per la parte nella elseclausola sarebbe

from .. import one

A pensarci bene, questo probabilmente non risolverà il tuo problema specifico. Ho frainteso la domanda e ho pensato che two.py fosse gestito come il modulo principale, ma non è così. E considerando le differenze nel modo in cui Python 2.6 (senza importare absolute_importda __future__) e Python 3.x gestiscono le importazioni, non dovresti farlo comunque per Python 2.6, non credo.

Tuttavia, se alla fine si passa a Python 3 e si prevede di utilizzare un modulo sia come modulo pacchetto sia come script autonomo all'interno del pacchetto, potrebbe essere una buona idea mantenere qualcosa come

if __name__ == '__main__':
    from [whatever the name of your package is] import one   # assuming the package is in the current working directory or a subdirectory of PYTHONPATH
else:
    from .. import one

in mente.

EDIT: E ora per una possibile soluzione al tuo problema reale. O esegui PyLint dalla directory che contiene il tuo onemodulo (tramite la riga di comando, forse) o metti il ​​seguente codice da qualche parte quando esegui PyLint:

import os

olddir = os.getcwd()
os.chdir([path_of_directory_containing_module_one])
import one
os.chdir(olddir)

Fondamentalmente, in alternativa alla manipolazione di PYTHONPATH, assicurati che la directory di lavoro corrente sia la directory che contiene one.pyquando esegui l'importazione.

(Guardando la risposta di Brian, potresti probabilmente assegnare il codice precedente a init_hook, ma se hai intenzione di farlo, potresti semplicemente fare l'aggiunta a sys.pathquello che fa, che è leggermente più elegante della mia soluzione.)


2

La chiave è aggiungere la directory del progetto a sys.pathsenza considerare la variabile env.

Per qualcuno che usa VSCode, ecco una soluzione a una riga per te se c'è una directory di base del tuo progetto:

[MASTER]
init-hook='base_dir="my_spider"; import sys,os,re; _re=re.search(r".+\/" + base_dir, os.getcwd()); project_dir = _re.group() if _re else os.path.join(os.getcwd(), base_dir); sys.path.append(project_dir)'

Lasciami spiegare un po ':

  • re.search(r".+\/" + base_dir, os.getcwd()).group(): trova la directory di base in base al file di modifica

  • os.path.join(os.getcwd(), base_dir): aggiungi cwda sys.pathper soddisfare l'ambiente della riga di comando


Cordiali saluti, ecco il mio .pylintrc:

https://gist.github.com/chuyik/f0ffc41a6948b6c87c7160151ffe8c2f


2

Ho avuto lo stesso problema e risolto installando pylint nel mio virtualenv e quindi aggiungendo un file .pylintrc alla mia directory di progetto con il seguente nel file:

[Master]
init-hook='sys.path = list(); sys.path.append("./Lib/site-packages/")'

Devo confermare che questo elimina gli errori del pylint E0611, ma gli errori E0401 rimangono.
np8,

1

Forse aggiungendo manualmente la directory all'interno di PYTHONPATH?

sys.path.append(dirname)

Hmm, ma dove metteresti quel codice? Nella parte superiore di ogni singolo file? Suppongo che funzionerebbe, ma è piuttosto un trucco solo per far funzionare PyLint.
EMP,

@Evgeny: vedi la risposta che Brian M. Hunt ha pubblicato di recente.
JAB,

E l'aggiunta di questo nella parte superiore di ogni file non funziona per qualche motivo: PyLint sembra perfettamente contenuto per ignorare qualsiasi modifica apportata a sys.path dall'interno dei moduli che sta eseguendo la scansione. Non mi sono preoccupato di fare ricerche sul perché, però ...
javawizard,

1

Ho avuto lo stesso problema e poiché non sono riuscito a trovare una risposta, spero che questo possa aiutare chiunque abbia un problema simile.

Uso flymake con epylint. Fondamentalmente quello che ho fatto è stato aggiungere un hook in modalità dired che controlla se la directory dired è una directory del pacchetto python. Se lo è, lo aggiungo al PYTHONPATH. Nel mio caso considero una directory un pacchetto python se contiene un file chiamato "setup.py".

;;;;;;;;;;;;;;;;;
;; PYTHON PATH ;;
;;;;;;;;;;;;;;;;;

(defun python-expand-path ()
  "Append a directory to the PYTHONPATH."
  (interactive
   (let ((string (read-directory-name 
          "Python package directory: " 
          nil 
          'my-history)))
     (setenv "PYTHONPATH" (concat (expand-file-name string)
                  (getenv ":PYTHONPATH"))))))

(defun pythonpath-dired-mode-hook ()
  (let ((setup_py (concat default-directory "setup.py"))
    (directory (expand-file-name default-directory)))
    ;;   (if (file-exists-p setup_py)
    (if (is-python-package-directory directory)
    (let ((pythonpath (concat (getenv "PYTHONPATH") ":" 
                  (expand-file-name directory))))
      (setenv "PYTHONPATH" pythonpath)
      (message (concat "PYTHONPATH=" (getenv "PYTHONPATH")))))))

(defun is-python-package-directory (directory)
  (let ((setup_py (concat directory "setup.py")))
    (file-exists-p setup_py)))

(add-hook 'dired-mode-hook 'pythonpath-dired-mode-hook)

Spero che questo ti aiuti.


1

Nel caso in cui qualcuno stia cercando un modo per eseguire il pylint come strumento esterno in PyCharm e farlo funzionare con i loro ambienti virtuali (perché sono arrivato a questa domanda), ecco come l'ho risolto:

  1. In PyCharm> Preferenze> Strumenti> Strumenti esterni, aggiungi o modifica un elemento per pylint.
  2. Nella finestra Impostazioni strumento della finestra di dialogo Modifica strumento, imposta Programma per usare pylint dalla directory dell'interprete python: $PyInterpreterDirectory$/pylint
  3. Imposta i tuoi altri parametri nel campo Parametri, come: --rcfile=$ProjectFileDir$/pylintrc -r n $FileDir$
  4. Imposta la tua directory di lavoro su $FileDir$

Ora l'utilizzo di pylint come strumento esterno eseguirà pylint su qualsiasi directory selezionata utilizzando un file di configurazione comune e utilizzerà qualsiasi interprete configurato per il progetto (che presumibilmente è il tuo interprete virtualenv).


1

Questa è una vecchia domanda ma non ha una risposta accettata, quindi suggerirò questo: cambia l'istruzione import in two.py per leggere:

from .. import one

Nel mio ambiente attuale (Python 3.6, VSCode usando pylint 2.3.1) questo cancella l'istruzione contrassegnata.


1

Ho trovato una bella risposta . Modifica il tuo pilastro e aggiungi quanto segue in master

init-hook="import imp, os; from pylint.config import find_pylintrc; imp.load_source('import_hook', os.path.join(os.path.dirname(find_pylintrc()), 'import_hook.py'))"

1

Quando installi Python, puoi impostare il percorso. Se il percorso è già definito, ciò che puoi fare è all'interno di VS Code, premi Ctrl + Maiusc + P e digita Python: seleziona Interprete e seleziona la versione aggiornata di Python. Segui questo link per ulteriori informazioni, https://code.visualstudio.com/docs/python/environments



0

Se stai usando Cython in Linux, ho risolto la rimozione dei module.cpython-XXm-X-linux-gnu.sofile nella directory di destinazione del mio progetto.


0

basta aggiungere questo codice nel file .vscode / settings.json

, "python.linting.pylintPath": "venv / bin / pylint"

Questo avviserà la posizione di pylint (che è un controllo errori per Python)


-1

Ciao sono stato in grado di importare i pacchetti da directory diverse. Ho appena fatto quanto segue: Nota: sto usando VScode

I passaggi per creare un pacchetto Python Lavorare con i pacchetti Python è davvero semplice. Tutto quello che devi fare è:

Crea una directory e assegnagli il nome del pacchetto. Metti le tue lezioni dentro. Creare un file init .py nella directory

Ad esempio: hai una cartella chiamata Framework in cui tieni tutte le classi personalizzate lì e il tuo compito è semplicemente creare un file init .py all'interno della cartella denominata Framework.

E durante l'importazione devi importare in questo modo --->

dalla base di importazione Framework

quindi l'errore E0401 scompare Framework è la cartella in cui hai appena creato init .py e base è il tuo modulo personalizzato in cui devi importare e lavorare su Spero che sia d'aiuto !!!!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.