Wie organisieren Sie ein Python-Projekt, das mehrere Pakete enthält, sodass jede Datei in einem Paket noch einzeln ausgeführt werden kann?
TL; DR
Hier ist ein Beispielrepository, das wie im ersten Diagramm (unten) beschrieben eingerichtet ist:https: //github.com/Poddster/package_problem
Wenn Sie es in Bezug auf die Projektorganisation wie im zweiten Diagramm aussehen lassen und dennoch die folgenden Befehle ausführen können, haben Sie die Frage beantwortet:
$ git clone https://github.com/Poddster/package_problems.git
$ cd package_problems
<do your magic here>
$ nosetests
$ ./my_tool/my_tool.py
$ ./my_tool/t.py
$ ./my_tool/d.py
(or for the above commands, $ cd ./my_tool/ && ./my_tool.py is also acceptable)
Alternativ: Geben Sie mir eine andere Projektstruktur, mit der ich zusammengehörige Dateien ('Paket') gruppieren, alle Dateien einzeln ausführen, die Dateien in andere Dateien im selben Paket importieren und die Pakete / Dateien in andere Pakete importieren kann Dateien.
Momentane SituatioIch habe ein paar Python-Dateien. Die meisten von ihnen sind nützlich, wenn sie über die Befehlszeile aufgerufen werden können, d. H. Sie verwenden alle argparse und if __name__ == "__main__"
nützliche Dinge zu tun.
erzeit habe ich diese Verzeichnisstruktur und alles funktioniert einwandfrei:
.
├── config.txt
├── docs/
│ ├── ...
├── my_tool.py
├── a.py
├── b.py
├── c.py
├── d.py
├── e.py
├── README.md
├── tests
│ ├── __init__.py
│ ├── a.py
│ ├── b.py
│ ├── c.py
│ ├── d.py
│ └── e.py
└── resources
├── ...
Einige der Skripteimport
Dinge aus anderen Skripten, um ihre Arbeit zu erledigen. Aber kein Skript ist nur eine Bibliothek, sie sind alle aufrufbar. z.B. Ich könnte @ aufruf./my_tool.py
, ./a.by
, ./b.py
, ./c.py
etc und sie würden nützliche Dinge für den Benutzer tun.
"my_tool.py" ist das Hauptskript, das alle anderen Skripte nutzt.
Was ich machen willIch möchte jedoch die Art und Weise ändern, in der das Projekt organisiert ist. Das Projekt selbst stellt ein gesamtes Programm dar, das vom Benutzer verwendet werden kann, und wird als solches vertrieben. Ich weiß jedoch, dass Teile davon später in verschiedenen Projekten nützlich sein werden. Daher möchte ich versuchen, die aktuellen Dateien in einem Paket zusammenzufassen. In naher Zukunft werde ich diesem Projekt auch andere Pakete hinzufügen.
Um dies zu vereinfachen, habe ich beschlossen, das Projekt in etwa wie folgt neu zu organisieren:
.
├── config.txt
├── docs/
│ ├── ...
├── my_tool
│ ├── __init__.py
│ ├── my_tool.py
│ ├── a.py
│ ├── b.py
│ ├── c.py
│ ├── d.py
│ ├── e.py
│ └── tests
│ ├── __init__.py
│ ├── a.py
│ ├── b.py
│ ├── c.py
│ ├── d.py
│ └── e.py
├── package2
│ ├── __init__.py
│ ├── my_second_package.py
| ├── ...
├── README.md
└── resources
├── ...
Ich kann jedoch keine Projektorganisation finden, die die folgenden Kriterien erfüllt:
Alle Skripte können in der Befehlszeile aufgerufen werden (entweder alsmy_tool\a.py
odercd my_tool && a.py
)Die Tests laufen tatsächlich:)Dateien in package2 könnenimport my_tool
Das Hauptproblem liegt in den von den Paketen und den Tests verwendeten Importanweisungen.
erzeit tun alle Pakete, einschließlich der Tests, einfachimport <module>
und es ist richtig gelöst. Aber wenn man Dinge herumwirbelt, funktioniert das nicht.
Bitte beachten Sie, dass die Unterstützung von py2.7 eine Voraussetzung ist, sodass alle Dateien @ habefrom __future__ import absolute_import, ...
oben
Wenn ich die Dateien wie oben gezeigt verschiebe, aber alle Importanweisungen unverändert lasse:
$ ./my_tool/*.py
funktioniert und sie laufen alle richtig$ nosetests
vom obersten Verzeichnis ausführen funktioniert nicht. Die Tests können die Paketskripte nicht importieren.pycharm hebt beim Bearbeiten dieser Dateien die Importanweisungen rot hervor: 2Wenn ich dann die Testskripte ändere:
from my_tool import x
$ ./my_tool/*.py
funktioniert immer noch und sie laufen alle richtig$ nosetests
vom obersten Verzeichnis ausführen funktioniert nicht. Dann können Tests die richtigen Skripte importieren, aber die Importe in die Skripte selbst schlagen fehl, wenn die Testskripte sie importieren.pycharm hebt die Importanweisungen in den Hauptskripten noch rot hervor: 3Wenn ich die gleiche Struktur behalte und änderealle seinfrom my_tool import
dann
$ ./my_tool/*.py
ergibtImportError
s$ nosetests
läuft alles in Ordnung.pycharm beschwert sich über nichtsz.B. von 1.
Traceback (most recent call last):
File "./my_tool/a.py", line 34, in <module>
from my_tool import b
ImportError: cannot import name b
4 Ich habe es auch versuchtfrom . import x
aber das endet nur mitValueError: Attempted relative import in non-package
zum direkten Ausführen von Skripten.
Ich kann nicht einfach @ verwendpython -m pkg.tests.core_test
wi
a) Ich habe keinMai .py. Ich denke, ich könnte eine haben?
b) Ich möchte alle Skripte ausführen können, nicht nur main?
Ich habe es versucht
if __name__ == '__main__' and __package__ is None:
from os import sys, path
sys.path.append(path.dirname(path.dirname(path.abspath(__file__))))
aber es hat nicht geholfen.
Ich habe auch versucht:
__package__ = "my_tool"
from . import b
Aber erhalten:
SystemError: Parent module 'loading_tool' not loaded, cannot perform relative import
addingimport my_tool
Vorfrom . import b
endet gerade wieder mitImportError: cannot import name b
Was sind die richtigen magischen Beschwörungsformeln und das richtige Verzeichnislayout, damit all dies funktioniert?