2010-09-05 25 views
11

Estoy ejecutando Python 2.6.1 en Windows XP SP3. Mi IDE es PyCharm 1.0-Beta 2 build PY-96.1055.Python "ImportError: Ningún módulo llamado" Problema

Estoy almacenando mis archivos .py en un directorio llamado "src"; tiene un archivo __init__.py que está vacío excepto por un atributo "__author__" en la parte superior.

Uno de ellos se llama 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() 

He creado un nuevo directorio llamado "test", que también tiene un archivo __init__.py que está vacía a excepción de un atributo "__author__" en la parte superior. He creado una unidad de MatrixTest.py a mi clase 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) 

Sin embargo, cuando trato de ejecutar mi MatrixTest consigo este error:

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 

Todo lo que he leído me dice que tiene el init .py en todos mis directorios deberían encargarse de esto.

Si alguien pudiera señalar lo que me he perdido, lo agradecería mucho.

También me gustaría recibir consejos sobre la mejor manera de desarrollar y mantener clases de prueba de fuente y unidad. Estoy pensando en esto de la forma en que suelo hacerlo cuando escribo Java:/src y/test directories, con estructuras de paquete idénticas debajo. ¿Es este pensamiento "Ptónico", o debería considerar otro esquema de organización?

ACTUALIZACIÓN:

Gracias a los que han contestado, aquí está la solución que funcionó para mí:

  1. Cambio de importación para que from src import Matrix # Matrix class to be tested
  2. Añadir sys.path como una variable de entorno para la configuración de mi unittest, con ./src y ./test directorios separados por punto y coma.
  3. Cambie las declaraciones en MatrixTest.py como se muestra.
+0

¿Dice que sus archivos están almacenados en una carpeta src? C: \ Tools \ Python-2.6.1 \ python.exe "C:/Documentos y configuración/Michael/Mis documentos/Proyectos/Python/learning/core/test/MatrixTest.py" – awithrow

+1

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

Respuesta

14

Esto es un poco de una suposición, pero creo que necesita para variable de entorno change your PYTHONPATH para incluir los directorios src y de prueba.

Es posible que los programas en ejecución en el directorio src hayan estado funcionando, porque Python inserta automáticamente el directorio del script que se está ejecutando actualmente en sys.path. Por lo tanto, importar módulos en src habría funcionado siempre y cuando también esté ejecutando un script que se encuentre en src.

Pero ahora que está ejecutando un script desde test, el directorio test se añade automáticamente a sys.path, mientras src no lo es.

Todos los directorios enumerados en PYTHONPATH se agregan a sys.path, y Python busca sys.path para buscar módulos.

Además, si usted dice

from src import Matrix 

continuación Matrix se referiría al paquete, y que había necesidad de decir Matrix.Matrix acceder a la clase.

+0

@Cristian: puse 'import sys; print (sys.path) 'en un archivo llamado test.py. Luego ejecuté 'cd/some/other/dir; python/ruta/a/prueba.py'. La primera ruta enumerada es '/ ruta/a', no'/some/other/dir'. Entonces aparece el directorio del script, no el CWD que se agrega a 'sys.path'. – unutbu

+0

@ ~ unutbu: ¡tienes razón! El motivo de mi comentario fue este fragmento del [tutorial] (http://docs.python.org/tutorial/modules.html#the-module-search-path): "Cuando se importa un módulo llamado spam, el intérprete busca un archivo llamado spam.py en el * directorio actual *, y luego en la lista de directorios especificados por la variable de entorno PYTHONPATH. ". Supongo que alguien debería reformularlo de una manera menos ambigua. –

+1

@ Christian: Hmm, eso ciertamente es confuso. (Sin embargo, trata de aclarar en el segundo párrafo). Aquí hay otro enlace a los documentos; este creo que es más claro: http://docs.python.org/library/sys.html#sys.path – unutbu

1

Con respecto a las mejores prácticas, PycURL utiliza un directorio tests en el mismo nivel que el código fuente principal. Por otro lado, proyectos como Twisted o sorl-thumbnail usan un subdirectorio test(s) bajo el código fuente principal.

La otra mitad de la pregunta ya ha sido respondida por ~unutbu.

+1

Hola Christian, gracias por el ejemplo. Prefiero la forma en que lo haces:/src y/test en el mismo nivel. – duffymo

Cuestiones relacionadas