ti-enxame.com

Python "ImportError: nenhum módulo chamado" Problema

Estou executando o Python 2.6.1 no Windows XP SP3. Meu IDE é o PyCharm 1.0-Beta 2 build PY-96.1055.

Estou armazenando meus arquivos .py em um diretório chamado "src"; ele tem um arquivo __init__.py vazio, exceto por um atributo "__author__" na parte superior.

Um deles é chamado 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()

Eu criei um novo diretório chamado "teste" que também possui um arquivo __init__.py Vazio, exceto por um atributo "__author__" Na parte superior. Eu criei um MatrixTest.py para unidade minha 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)

No entanto, quando tento executar meu MatrixTest, recebo este erro:

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

Tudo o que li me diz que ter o init. Py em todos os meus diretórios deve cuidar disso.

Se alguém pudesse apontar o que eu perdi, eu apreciaria muito.

Eu também gostaria de receber conselhos sobre a melhor maneira de desenvolver e manter as classes de origem e teste de unidade. Estou pensando nisso da maneira que costumo fazer quando escrevo diretórios Java:/src e/test, com estruturas de pacotes idênticas por baixo. Esse pensamento é "pitonico" ou devo considerar outro esquema organizacional?

ATUALIZAR:

Graças a quem respondeu, aqui está a solução que funcionou para mim:

  1. Altere a importação para from src import Matrix # Matrix class to be tested
  2. Adicione sys.path Como uma variável de ambiente à minha configuração mais unittest, com os diretórios ./src e ./test separados por ponto e vírgula.
  3. Altere as declarações em MatrixTest.py, como mostrado.
17
duffymo

Isso é um palpite, mas acho que você precisa alterar sua variável de ambiente PYTHONPATH para incluir os diretórios src e test.

A execução de programas no diretório src pode estar funcionando, porque Python insere automaticamente o diretório do script em que está sendo executado atualmente no sys.path. Portanto, importar módulos em src teria funcionado desde que você também estivesse executando um script que reside em src.

Mas agora que você está executando um script a partir de test, o diretório test é adicionado automaticamente a sys.path, enquanto src não for.

Todos os diretórios listados em PYTHONPATH são adicionados a sys.path e Python pesquisa sys.path para encontrar módulos.

Além disso, se você disser

from src import Matrix

então Matrix se referiria ao pacote e você precisaria dizer Matrix.Matrix para acessar a classe.

17
unutbu

Em relação às melhores práticas, PycURL usa um diretório tests no mesmo nível do código-fonte principal. Por outro lado, projetos como Twisted ou sorl-thumbnail usam um subdiretório test(s) no código-fonte principal.

A outra metade da pergunta já foi respondida por ~ unutb .

1
Cristian Ciupitu