2010-09-05 2 views
11

Я запускаю Python 2.6.1 на Windows XP SP3. Моя IDE - это PyCharm 1.0-Beta 2 build PY-96.1055.Python "ImportError: No module named" Проблема

Я храню свои .py файлы в каталоге с именем «src»; у него есть файл __init__.py, который пуст, за исключением атрибута «__author__» вверху.

Один из них называется 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() 

Я создал новый каталог с именем «тест», которое также имеет __init__.py файл, который пуст для «__author__» атрибута в верхней части, за исключением. Я создал MatrixTest.py к блоку моего 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) 

Но когда я пытаюсь запустить мой MatrixTest я получаю эту ошибку:

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 

Все, что я читал говорит мне, что с init .py во всех моих каталогах следует позаботиться об этом.

Если кто-то может указать, что я пропустил, я бы очень признателен.

Я также хотел бы посоветоваться, как наилучшим образом разработать и поддерживать классы тестирования источника и единицы измерения. Я думаю об этом так, как обычно, когда пишу Java:/src и/test каталоги, с одинаковыми структурами пакетов внизу. Является ли это «питоническим» мышлением, или я должен рассмотреть другую схему организации?

UPDATE:

Спасибо тем, кто ответил, вот решение, которое работает для меня:

  1. Изменение импорта в from src import Matrix # Matrix class to be tested
  2. Добавить sys.path в качестве переменной окружения к моей конфигурации UnitTest, с ./src и ./test каталоги, разделенные точкой с запятой.
  3. Измените объявления в MatrixTest.py, как показано.
+0

Вы говорите, что ваши файлы хранятся в папке src? C: \ Tools \ Python-2.6.1 \ python.exe "C:/Documents and Settings/Michael/Мои документы/Проекты/Python/learning/core/test/MatrixTest.py" – awithrow

+1

Используйте 'python -m test.MatrixTest '. См. Http://stackoverflow.com/questions/24622041/python-importing-a-module-from-a-parallel-directory – jrc

ответ

14

Это немного догадки, но я думаю, что вам нужно переменную change your PYTHONPATH среды включить СРК и тестовые каталоги.

Возможно, запущены программы в каталоге src, потому что Python автоматически вставляет каталог скрипта, который в настоящее время запущен в sys.path. Поэтому импорт модулей в src работал бы до тех пор, пока вы также выполняете скрипт, который находится в src.

Но теперь, когда вы запускаете скрипт из test, каталог test автоматически добавляется sys.path, а src нет.

Все каталоги, перечисленные в PYTHONPATH, добавляются в sys.path, а Python ищет sys.path для поиска модулей.

Кроме того, если вы говорите,

from src import Matrix 

тогда Matrix будет относиться к пакету, и вы должны были бы сказать Matrix.Matrix, чтобы получить доступ к классу.

+0

@Cristian: Я положил 'import sys; print (sys.path) 'в файле с именем test.py. Затем я запускал 'cd/some/other/dir; python/path/to/test.py'. Первым указанным путем является '/ path/to', а не'/some/other/dir'. Таким образом, он отображается в каталоге сценария, а не в CWD, который добавлен в 'sys.path'. – unutbu

+0

@ ~ unutbu: вы правы! Причиной моего комментария был этот фрагмент из [учебника] (http://docs.python.org/tutorial/modules.html#the-module-search-path): «Когда импортируется модуль со спамом, интерпретатор ищет файл с именем spam.py в * текущем каталоге *, а затем в списке каталогов, заданных переменной среды PYTHONPATH. ". Думаю, кто-то должен перефразировать его менее двусмысленно. –

+1

@Cristian: Хм, это определенно сбивает с толку. (Хотя, он пытается уточнить во втором абзаце). Вот еще одна ссылка на документы; этот, я думаю, более ясен: http://docs.python.org/library/sys.html#sys.path – unutbu

1

Что касается передового опыта, то PycURL использует каталог tests на уровне, соответствующем основному исходному коду. С другой стороны, проекты, такие как Twisted или sorl-thumbnail, используют подкаталог test(s) под основным исходным кодом.

Другие вопросы возникли вопросы ~unutbu.

+1

Привет, христианин, Спасибо за пример. Я предпочитаю, как вы это делаете:/src и/test на том же уровне. – duffymo