2010-09-05 3 views
11

Ich verwende Python 2.6.1 unter Windows XP SP3. Meine IDE ist PyCharm 1.0-Beta 2 Build PY-96.1055.Python "ImportError: Kein Modul namens" Problem

Ich speichere meine .py-Dateien in einem Verzeichnis namens "src"; Es hat eine __init__.py Datei, die bis auf ein "__author__" Attribut an der Spitze leer ist.

Einer von ihnen ist Matrix.py genannt:

#!/usr/bin/env python 
""" 
"Core Python Programming" chapter 6. 
A simple Matrix class that allows addition and multiplication 
""" 
__author__ = 'Michael' 
__credits__ = [] 
__version__ = "1.0" 
__maintainer__ = "Michael" 
__status__ = "Development" 

class Matrix(object): 
    """ 
    exercise 6.16: MxN matrix addition and multiplication 
    """ 
    def __init__(self, rows, cols, values = []): 
     self.rows = rows 
     self.cols = cols 
     self.matrix = values 

    def show(self): 
     """ display matrix""" 
     print '[' 
     for i in range(0, self.rows): 
      print '(', 
      for j in range(0, self.cols-1): 
       print self.matrix[i][j], ',', 
      print self.matrix[i][self.cols-1], ')' 
     print ']' 

    def get(self, row, col): 
     return self.matrix[row][col] 

    def set(self, row, col, value): 
     self.matrix[row][col] = value 

    def rows(self): 
     return self.rows 

    def cols(self): 
     return self.cols 

    def add(self, other): 
     result = [] 
     for i in range(0, self.rows): 
      row = [] 
      for j in range(0, self.cols): 
       row.append(self.matrix[i][j] + other.get(i, j)) 
      result.append(row) 
     return Matrix(self.rows, self.cols, result) 

    def mul(self, other): 
     result = [] 
     for i in range(0, self.rows): 
      row = [] 
      for j in range(0, other.cols): 
       sum = 0 
       for k in range(0, self.cols): 
        sum += self.matrix[i][k]*other.get(k,j) 
       row.append(sum) 
      result.append(row) 
     return Matrix(self.rows, other.cols, result) 

    def __cmp__(self, other): 
     """ 
     deep equals between two matricies 
     first check rows, then cols, then values 
     """ 
     if self.rows != other.rows: 
      return self.rows.cmp(other.rows) 
     if self.cols != other.cols: 
      return self.cols.cmp(other.cols) 
     for i in range(0, self.rows): 
      for j in range(0, self.cols): 
       if self.matrix[i][j] != other.get(i,j): 
        return self.matrix[i][j] == (other.get(i,j)) 
     return True # if you get here, it means size and values are equal 



if __name__ == '__main__': 
    a = Matrix(3, 3, [[1, 2, 3], [4, 5, 6], [7, 8, 9]]) 
    b = Matrix(3, 3, [[6, 5, 4], [1, 1, 1], [2, 1, 0]]) 
    c = Matrix(3, 3, [[2, 0, 0], [0, 2, 0], [0, 0, 2]]) 
    a.show() 
    b.show() 
    c.show() 
    a.add(b).show() 
    a.mul(c).show() 

Ich habe ein neues Verzeichnis erstellt mit dem Namen „test“, die auch eine __init__.py Datei hat, die an der Spitze mit Ausnahme eines „__author__“ Attribut leer ist. Ich habe eine MatrixTest.py zu Einheit meine Matrix-Klasse erstellt:

#!/usr/bin/env python 
""" 
Unit test case for Matrix class 
See http://jaynes.colorado.edu/PythonGuidelines.html#module_formatting for Python coding guidelines 
""" 

import unittest #use my unittestfp instead for floating point 
from src import Matrix # Matrix class to be tested 

__author__ = 'Michael' 
__credits__ = [] 
__license__ = "GPL" 
__version__ = "1.0" 
__maintainer__ = "Michael" 
__status__ = "Development" 

class MatrixTest(unittest.TestCase): 
    """Unit tests for Matrix class""" 
    def setUp(self): 
     self.a = Matrix.Matrix(3, 3, [[1, 2, 3], [4, 5, 6], [7, 8, 9]]) 
     self.b = Matrix.Matrix(3, 3, [[6, 5, 4], [1, 1, 1], [2, 1, 0]]) 
     self.c = Matrix.Matrix(3, 3, [[2, 0, 0], [0, 2, 0], [0, 0, 2]]) 

    def testAdd(self): 
     expected = Matrix.Matrix(3, 3, [[7, 7, 7], [5, 6, 7], [9, 9, 9]]) # need to learn how to write equals for Matrix 
     self.a.add(self.b) 
     assert self.a == expected 

if __name__ == '__main__': #run tests if called from command-line 
    suite = unittest.TestLoader().loadTestsFromTestCase(TestSequenceFunctions) 
    unittest.TextTestRunner(verbosity=2).run(suite) 

Aber wenn ich versuche, meine MatrixTest ich diesen Fehler zu laufen:

C:\Tools\Python-2.6.1\python.exe "C:/Documents and Settings/Michael/My Documents/Projects/Python/learning/core/test/MatrixTest.py" 
Traceback (most recent call last): 
    File "C:/Documents and Settings/Michael/My Documents/Projects/Python/learning/core/test/MatrixTest.py", line 8, in <module> 
    from src import Matrix # Matrix class to be tested 
ImportError: No module named src 

Process finished with exit code 1 

Alles, was ich gelesen habe, sagt mir, dass mit Die init .py in allen meinen Verzeichnissen sollte darauf achten.

Wenn jemand darauf hinweisen könnte, was ich verpasst habe, würde ich es sehr schätzen.

Ich hätte auch gerne Ratschläge für die beste Art und Weise, Quell- und Einheitentestklassen zu entwickeln und zu pflegen. Ich denke darüber nach, wie ich es normalerweise mache, wenn ich Java schreibe:/src und/test Verzeichnisse, mit identischen Paketstrukturen darunter. Spricht das "Pythonic", oder sollte ich ein anderes Organisationsschema in Erwägung ziehen?

UPDATE:

Dank denen, die geantwortet haben, hier ist die Lösung, die für mich gearbeitet:

  1. ändern Import from src import Matrix # Matrix class to be tested
  2. hinzufügen sys.path als Umgebungsvariable meiner Unittest-Konfiguration, mit ./src und ./test Verzeichnisse durch Semikolon getrennt.
  3. Ändern Sie die Deklarationen in MatrixTest.py wie gezeigt.
+0

Sie sagen, dass Ihre Dateien in einem src-Ordner gespeichert sind? C: \ Tools \ Python-2.6.1 \ python.exe "C:/Dokumente und Einstellungen/Michael/Meine Dokumente/Projekte/Python/lernen/core/test/MatrixTest.py" – awithrow

+1

Verwenden Sie 'python -m test.MatrixTest '. Siehe http://stackoverflow.com/questions/24622041/python-importing-a-module-from-a-parallel-directory – jrc

Antwort

14

Das ist ein bisschen eine Vermutung, aber ich glaube, Sie zu change your PYTHONPATH Umgebungsvariable müssen die src und Test-Verzeichnisse aufzunehmen.

Das Ausführen von Programmen im Verzeichnis src funktioniert möglicherweise, weil Python das Verzeichnis des gerade ausgeführten Skripts automatisch in sys.path einfügt. Das Importieren von Modulen in src hätte also funktioniert, solange Sie auch ein Skript ausführen, das sich in src befindet.

Aber jetzt, dass Sie ein Skript aus test ausgeführt werden, wird das test Verzeichnis sys.path, automatisch hinzugefügt, während src nicht ist.

Alle in PYTHONPATH aufgelisteten Verzeichnisse werden zu sys.path hinzugefügt, und Python sucht sys.path, um Module zu finden.

Auch wenn Sie sagen

from src import Matrix 

dann Matrix auf das Paket beziehen würde, und Sie müssen Matrix.Matrix sagen, die Klasse zuzugreifen.

+0

@Cristian: Ich habe 'import sys; print (sys.path) 'in einer Datei namens test.py. Dann habe ich 'cd/some/other/dir; Python/Pfad/zu/test.py'. Der erste Pfad ist '/ path/to', nicht'/some/other/dir'. Es erscheint also das Verzeichnis des Skripts, nicht das CWD, das zu 'sys.path' hinzugefügt wird. – unutbu

+0

@ ~ unutbu: du hast Recht! Der Grund für meinen Kommentar war dieser Ausschnitt aus dem [Tutorial] (http://docs.python.org/tutorial/modules.html#the-module-search-path): "Wenn ein Modul namens Spam importiert wird, der Interpreter sucht nach einer Datei namens spam.py im * aktuellen Verzeichnis * und dann in der Liste der Verzeichnisse, die von der Umgebungsvariablen PYTHONPATH angegeben werden. ". Ich denke, jemand sollte es auf weniger zweideutige Weise umformulieren. –

+1

@Cristian: Hmm, das ist sicherlich verwirrend. (Obwohl es versucht, im zweiten Absatz zu klären). Hier ist ein weiterer Link zu den Dokumenten; diese denke ich ist klarer: http://docs.python.org/library/sys.html#sys.path – unutbu

1

In Bezug auf Best Practices verwendet PycURL ein Verzeichnis tests auf derselben Ebene wie der Hauptquellcode. Auf der anderen Seite verwenden Projekte wie Twisted oder sorl-thumbnail ein test(s) Unterverzeichnis unter dem Hauptquellcode. Die andere Hälfte der Frage wurde bereits von ~unutbu beantwortet.

+1

Hallo Christian, vielen Dank für das Beispiel. Ich bevorzuge die Art und Weise, wie Sie es tun:/src und/test auf gleicher Ebene. – duffymo