web-dev-qa-db-fra.com

Python "ImportError: aucun module nommé" Problème

J'exécute Python 2.6.1 sous Windows XP SP3. Mon IDE est PyCharm 1.0-Beta 2 build PY) -96,1055.

Je stocke mes fichiers .py dans un répertoire nommé "src"; il a un __init__.py fichier vide à l'exception d'un "__author__ "attribut en haut.

L'un d'eux s'appelle Matrix.py:

#!/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()

J'ai créé un nouveau répertoire nommé "test" qui a également un __init__.py fichier vide à l'exception d'un "__author__ "en haut. J'ai créé un MatrixTest.py pour unir ma classe Matrix:

#!/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)

Pourtant, lorsque j'essaie d'exécuter mon MatrixTest, j'obtiens cette erreur:

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

Tout ce que j'ai lu me dit que d'avoir le init. Py dans tous mes répertoires devrait s'en occuper.

Si quelqu'un pouvait souligner ce que j'ai manqué, je l'apprécierais beaucoup.

J'aimerais aussi des conseils sur la meilleure façon de développer et de maintenir des classes de tests source et unitaire. J'y pense comme je le fais habituellement lorsque j'écris des répertoires Java:/src et/test, avec des structures de packages identiques en dessous. Est-ce une pensée "pythonique", ou devrais-je envisager un autre schéma d'organisation?

METTRE À JOUR:

Merci à ceux qui ont répondu, voici la solution qui a fonctionné pour moi:

  1. Remplacez l'importation par from src import Matrix # Matrix class to be tested
  2. Ajouter sys.path comme variable d'environnement dans ma configuration la plus simple, avec les répertoires ./src et ./test séparés par des points-virgules.
  3. Modifiez les déclarations dans MatrixTest.py comme indiqué.
18
duffymo

C'est un peu une supposition, mais je pense que vous devez changer votre PYTHONPATH variable d'environnement pour inclure les répertoires src et test.

L'exécution de programmes dans le répertoire src peut avoir fonctionné, car Python insère automatiquement le répertoire du script dans lequel il s'exécute actuellement sys.path. L'importation de modules dans src aurait donc fonctionné tant que vous exécutez également un script qui réside dans src.

Mais maintenant que vous exécutez un script à partir de test, le répertoire test est automatiquement ajouté à sys.path, tandis que src ne l'est pas.

Tous les répertoires répertoriés dans PYTHONPATH sont ajoutés à sys.path et Python recherche sys.path pour rechercher des modules.

Aussi, si vous dites

from src import Matrix

alors Matrix ferait référence au paquet, et vous auriez besoin de dire Matrix.Matrix pour accéder à la classe.

17
unutbu

Concernant les meilleures pratiques, PycURL utilise un répertoire tests au même niveau que le code source principal. D'un autre côté, les projets comme Twisted ou sorl-thumbnail utilisent un sous-répertoire test(s) sous le code source principal.

~ unutb a déjà répondu à l'autre moitié de la question.

1
Cristian Ciupitu