302 votes

PyLint "Unable to import" error - comment définir PYTHONPATH ?

Je lance PyLint à partir de l'IDE Wing sur Windows. J'ai un sous-répertoire (package) dans mon projet et à l'intérieur du package j'importe un module du niveau supérieur, ie.

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

A l'intérieur two.py J'ai import one et cela fonctionne bien au moment de l'exécution, parce que le répertoire de premier niveau (à partir duquel le système myapp.py est exécuté) se trouve dans le chemin d'accès à Python. Cependant, lorsque j'exécute PyLint sur two.py, il me donne une erreur :

F0401: Unable to import 'one'

Comment résoudre ce problème ?

34voto

muTheTechie Points 401

J'ai ajouté un nouveau fichier pylintrc dans le répertoire Root du projet avec

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

et cela fonctionne pour moi dans l'IDE PyCharm

32voto

macm Points 429

1) sys.path est une liste.

2) Le problème est que parfois le chemin sys.path n'est pas le chemin virtualenv.path. et vous voulez utiliser pylint dans votre virtualenv

3) Donc comme dit, utiliser init-hook (attention à ' et " l'analyse de pylint est stricte)

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

ou

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

et

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

9voto

simon Points 3630

Je ne sais pas comment cela fonctionne avec WingIDE, mais pour utiliser PyLint avec Geany, j'ai défini ma commande externe comme suit :

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

où %f est le nom du fichier et %d le chemin d'accès. Cela pourrait être utile à quelqu'un :)

5voto

bmoeskau Points 13136

J'ai dû mettre à jour le système PYTHONPATH pour ajouter le chemin d'accès à mon App Engine. Dans mon cas, je n'ai eu qu'à modifier mon ~/.bashrc et ajoutez la ligne suivante :

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

En fait, j'ai essayé de définir le init-hook mais cela n'a pas résolu le problème de manière cohérente dans ma base de code (je ne sais pas trop pourquoi). Une fois que je l'ai ajouté au chemin d'accès du système (probablement une bonne idée en général), mes problèmes ont disparu.

4voto

JAB Points 11053

Essayer

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

Notez qu'en Python 3, la syntaxe de la partie dans la balise else serait la suivante

from .. import one~~ 

À bien y réfléchir, cela ne résoudra probablement pas votre problème spécifique. J'ai mal compris la question et pensé que two.py était exécuté en tant que module principal, mais ce n'est pas le cas. Et compte tenu des différences dans la façon dont Python 2.6 (sans importation de absolute_import de __future__ ) et que Python 3.x gère les importations, vous n'auriez pas besoin de le faire pour Python 2.6 de toute façon, je ne pense pas.

Néanmoins, si vous passez finalement à Python 3 et que vous prévoyez d'utiliser un module à la fois comme module de paquetage et comme script autonome à l'intérieur du paquetage, il peut être judicieux de conserver quelque chose comme

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

à l'esprit.

EDIT : Et maintenant, une solution possible à votre problème actuel. Soit vous exécutez PyLint à partir du répertoire contenant votre fichier one (via la ligne de commande, par exemple), ou placez le code suivant quelque part lors de l'exécution de PyLint :

import os

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

En fait, au lieu de jouer avec PYTHONPATH, il suffit de s'assurer que le répertoire de travail courant est le répertoire contenant one.py lors de l'importation.

(En regardant la réponse de Brian, vous pourriez probablement assigner le code précédent à init_hook mais si vous voulez faire cela, vous pouvez simplement l'ajouter à sys.path qu'il fait, ce qui est légèrement plus élégant que ma solution).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X