2017-09-30 2 views
1

Ich mache eine einfache Python-App. Ich weiß nicht, ob ich es richtig mache oder nicht so korrigieren Sie mich bitte in den Kommentaren oder wenn Sie eine Antwort auf dieseImportError beim Ausführen von Python setup.py Test

Fehler: ImportError: No module named 'taskhandler' und ImportError: No module named 'styles' while doing python3 setup.py test`

Dateistruktur:

. 
├── MANIFEST.in 
├── pydotask.egg-info 
│   ├── dependency_links.txt 
│   ├── not-zip-safe 
│   ├── PKG-INFO 
│   ├── SOURCES.txt 
│   └── top_level.txt 
├── README.md 
├── setup.py 
├── task_mod 
│   ├── __init__.py 
│   ├── __pycache__ 
│   │   ├── __init__.cpython-35.pyc 
│   │   ├── pydo.cpython-35.pyc 
│   │   └── taskhandler.cpython-35.pyc 
│   ├── pydo.py 
│   ├── styles 
│   │   ├── __init__.py 
│   │   ├── __pycache__ 
│   │   │   ├── __init__.cpython-35.pyc 
│   │   │   ├── termcolor.cpython-35.pyc 
│   │   │   └── text_style.cpython-35.pyc 
│   │   ├── termcolor.py 
│   │   └── text_style.py 
│   ├── taskhandler.py 
│   └── tasks.csv 
└── update.txt 

5 directories, 22 files 

'task_mod/pydo.py':

#!/usr/bin/env python3 

''' To Do App in Python ''' 

import sys, os 
import taskhandler as task 
from styles import text_style as text 
from styles import termcolor 

task_mod/taskhandler.py:

#!/usr/bin/env python3 

import sys, os 
import csv 
from styles import termcolor 
from styles import text_style as text 

setup.py

from setuptools import setup 

def readme(): 
    with open('README.md') as readme: 
     return readme.read() 

setup(
     name = 'pydotask', 
     version = '0.2', 
     description = 'PyDo is a CLI Application to keep you on track with your tasks and projects', 
     long_description = readme(), 
     classifiers = [ 
      'Development Status :: 3 - Alpha', 
      'Programming Language :: Python :: 3.5', 
      'Topic :: Office/Business :: Scheduling' 
      ], 
     keywords = 'utilities office schedule task reminder', 
     url = '', 
     author = 'Abhishta Gatya', 
     author_email = '[email protected]', 
     packages = ['task_mod'], 
     scripts = ['task_mod/pydo'], 
     python_requires = '>=3', 
     include_package_data = True, 
     zip_safe = False 
     ) 

So, wie ich dieses Problem bekommen?

Hinweis: Wenn ich python3 task_mod/pydo.py ausführen, funktioniert es gut! aber wenn ich versuche es zu testen gibt es 2 Importfehler

+0

Ist das nicht wegen der Zeile '#!/Usr/bin/env python3' am Anfang von' pydo.py' und 'taskhandler.py'? – Iva

+0

@Iva das ist nur der Interpreter Pfad – Steampunkery

+0

ist das, was es verursacht hat? hängen Sie auf –

Antwort

1

Zuerst beachten Sie, dass Sie ein Paket task_mod in setup.py Namen geben. Es bedeutet, Sie sollten nur import task_mod oder import task_mod.blah, niemals import blah. Weil Sie blah nicht in Ihrer Bibliothek bereitstellen. Versuche die Importe auf die absoluten zu ändern.

Zweitens, wenn Sie immer noch einen relativen Import (dies ist eine gängige Praxis mit einer einzigen Bibliothek zu tun - es ist einfacher, den Code dann pflegen), sollten Sie relativ importieren: from .styles import termcolor (beachten Sie den Punkt).

Drittens die relativen Einfuhren betreffen nur die Module & Pakete, nicht die Skripte, die Sie direcly ausführen (weil pydo.py das Paket __main__, nicht task_mod.pydo, und es ändert sich alles). Für die Skripte haben Sie zwei Möglichkeiten, um es richtig zu machen:

Wahl A (so-so): Immer absolutes Paket/Modulname importieren (import task_mod.taskhandler as tashhandler in Ihrem pydo.py; auch from task_mod.styles import termcolor, usw.).

Auswahl B (bewährte Methode): Exportieren Sie keine Skripts als Teil der Bibliothek (nur für Bau-/Test-/CI/CD-Zwecke). Exportieren Sie stattdessen die Einstiegspunkte für die Konsolenskripte (Einstiegspunkte google: setuptools).

setup( .... entry_points={ 'console_scripts': [ 'pydo = task_mod.pydo:main', ], }, )

Und natürlich, definieren die main() Funktion in diesem Modul.

Die Shebangs (#!...python3) sind hier völlig irrelevant.


UPD:

Wenn Sie Probleme mit dem Import haben, bitte denken Sie daran:

Sie Ihr Paket auf dem PYTHONPATH env var (oder sys.path interne Variable) machen sollte , in gewisser Weise. Dies ist genau, wo Python nach Dingen sucht, wenn Sie import things tun.

Sie können print(sys.path) vor allen Importen zu sehen, warum es so passiert - das erste Element Ihres Skripts dir sein wird, und es wird zwischen task_mod/pydo.py & setup.py Anrufe werden variiert. Wenn Sie ein Skript im Hauptprojektverzeichnis ausführen (python3 setup.py), beginnt sys.path mit dem Projektverzeichnis. task_mod ist da, Sie können es importieren. Wenn Sie etwas wie pip install -e . tun, werden die Pakete auch in der Python/virtualenv-Liste der Bibliotheken "installiert", aber auf andere Weise. Wenn Sie python3 task_mod/pydo.py ausführen, ist das aktuelle Verzeichnis .../task_mod/. Dort können Sie das Paket task_mod nicht finden (weil es eine Ebene höher ist).

Auf der gegenüberliegenden Seite, wenn Ihr Lauf python3 setup.py, Ihr aktuelles dir Verzeichnis des Projekts ist, und Sie können nicht styles & taskhandler direkt importieren, wie Sie innitially tat (ohne sie von task_mod. zu prefixing).

Dies ist genau der Grund, warum Sie sich niemals auf die sys.path verlassen sollten, und verwenden Sie niemals die Skripte direkt und nehmen Sie ihren Speicherort an. Weil es variiert.

können Sie versuchen, PYTHONPATH=. python3 task_mod/pydo.py laufen sie das gleiche wie für setup.py funktioniert (oder PYTHONPATH=./task_mod/ python3 setup.py es das gleiche wie für task_mod/pydo.py zu machen). Aber das ist ein schmutziger Hack, damit es funktioniert. Stattdessen sollten Sie Ihre Bibliothek gemäß den Python-Konventionen richtig aufbauen.

+0

Dashbang? Meinst du shebang? – Steampunkery

+0

Hoppla. Ja, die Shebangs. Sorry :-) Behoben. –

+0

Wenn ich jetzt versuche, pydo.py auszuführen, bekomme ich einen ImportError, der sagt, kein Modul namens 'task_mod' –

2

Sie müssen alle Module angeben, die in setup.py verwendet werden, nicht nur den obersten Ordner. Ersetzen Sie in Ihrer setup.py-Datei die Zeile packages = ['task_mod'], durch packages = ['task_mod', 'task_mod.styles', 'task_mod.taskhandler'],.

Alternativ, ohne Ihre setup.py zu ändern, können Sie mit import task_mod.styles oder mit from task_mod import styles importieren. Dann können Sie Dateien in Stilen wie styles.termcolor verwenden.

Oder Sie können die setuptool schwarze Magie Funktion find_packages wie so verwenden: packages = find_packages(),

Related SO post

+0

Danke, es funktioniert! –

+1

Ich bin froh, Ihnen helfen zu können! – Steampunkery

Verwandte Themen