Paquetes de Python?

Ok, creo que sea lo que sea que esté haciendo mal, probablemente sea cegadoramente obvio, pero no puedo resolverlo. He leído y releído la sección de tutoriales sobre paquetes y lo único que puedo entender es que esto no funcionará porque lo estoy ejecutando directamente. Aquí está la configuración del directorio:

eulerproject/ __init__.py euler1.py euler2.py ... eulern.py tests/ __init__.py testeulern.py 

Aquí están los contenidos de testeuler12.py (el primer módulo de prueba que he escrito):

 import unittest from .. import euler12 class Euler12UnitTests(unittest.TestCase): def testtriangle(self): """ Ensure that the triangle number generator returns the first 10 triangle numbers. """ self.seq = [1,3,6,10,15,21,28,36,45,55] self.generator = euler12.trianglegenerator() self.results = [] while len(self.results) != 10: self.results.append(self.generator.next()) self.assertEqual(self.seq, self.results) def testdivisors(self): """ Ensure that the divisors function can properly factor the number 28. """ self.number = 28 self.answer = [1,2,4,7,14,28] self.assertEqual(self.answer, euler12.divisors(self.number)) if __name__ == '__main__': unittest.main() 

Ahora, cuando ejecuto esto desde IDLE y desde la línea de comandos mientras estoy en el directorio, obtengo el siguiente error:

 Traceback (most recent call last): File "C:\Documents and Settings\jbennet\My Documents\Python\eulerproject\tests\testeuler12.py", line 2, in  from .. import euler12 ValueError: Attempted relative import in non-package 

Creo que el problema es que, dado que lo ejecuto directamente, no puedo realizar importaciones relativas (porque __name__ cambia, y mi vaga comprensión de la descripción de los paquetes es que __name__ es parte de cómo dice en qué paquete está), pero en ese caso, ¿qué sugieren para importar el código de ‘producción’ almacenado 1 nivel desde el código de prueba?

En general, tendrá un directorio, cuyo nombre es el nombre de su paquete, en algún lugar de su PYTHONPATH. Por ejemplo:

 eulerproject/ euler/ __init__.py euler1.py ... tests/ ... setup.py 

Luego, puede instalar este sistema en todo el sistema o asegurarse de establecer PYTHONPATH=/path/to/eulerproject/:$PYTHONPATH cuando invoque su script.

Una importación absoluta como esta funcionará:

 from euler import euler1 

Editar :

De acuerdo con los documentos de Python, “los módulos diseñados para ser utilizados como el módulo principal de una aplicación de Python siempre deben usar importaciones absolutas”. ( Cita )

Así que un arnés de prueba como la nose , mencionado en la otra respuesta, funciona porque importa paquetes en lugar de ejecutarlos desde la línea de comandos.

Si quiere hacer las cosas a mano, su script ejecutable debe estar fuera de la jerarquía de paquetes, como esto:

 eulerproject/ runtests.py euler/ __init__.py euler1.py ... tests/ __init__.py testeulern.py 

Ahora, runtests.py puede hacer from euler.tests.testeulern import TestCase y testeulern.py puede hacer from .. import euler1

Yo tuve el mismo problema. Ahora uso la nariz para ejecutar mis pruebas, y las importaciones relativas se manejan correctamente.

Sí, todo este asunto de importancia relativa es confuso.