Importando desde una ruta relativa en Python

Tengo una carpeta para mi código de cliente, una carpeta para mi código de servidor y una carpeta para el código que se comparte entre ellos.

Proj/ Client/ Client.py Server/ Server.py Common/ __init__.py Common.py 

¿Cómo importo Common.py desde Server.py y Client.py?

EDITAR Nov 2014 (3 años después):

Python 2.6 y 3.x son compatibles con las importaciones relativas adecuadas, donde puedes evitar hacer cualquier cosa maliciosa. Con este método, sabe que está obteniendo una importación relativa en lugar de una importación absoluta . El “..” significa, vaya al directorio encima de mí:

 from ..Common import Common 

Como advertencia, esto solo funcionará si ejecuta Python como un módulo, desde fuera del paquete. Por ejemplo:

 python -m Proj 

Forma original hacky

Este método todavía se usa comúnmente en algunas situaciones, donde en realidad nunca está “instalando” su paquete. Por ejemplo, es popular entre los usuarios de Django.

Puedes agregar Común / a tu sys.path (la lista de rutas que Python busca para importar cosas):

 import sys, os sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'Common')) import Common 

os.path.dirname(__file__) solo le da el directorio en el que se encuentra su archivo python actual, y luego navegamos a ‘Common /’ el directorio e importamos ‘Common’ el módulo.

No hagas una importación relativa.

Desde PEP8 :

Las importaciones relativas para las importaciones dentro del paquete son altamente desalentadas.

Ponga todo su código en un súper paquete (es decir, “myapp”) y use subpaquetes para cliente, servidor y código común.

Actualización:Python 2.6 y 3.x admite importaciones relativas adecuadas (…) “. Ver las respuestas de Dave para más detalles.

¡Hacer una importación relativa es absolutamente OK! Esto es lo que el pequeño ‘ol me hace’:

 #first change the cwd to the script path scriptPath = os.path.realpath(os.path.dirname(sys.argv[0])) os.chdir(scriptPath) #append the relative location you want to import from sys.path.append("../common") #import your module stored in '../common' import common.py 

Lo suficientemente divertido, un mismo problema que acabo de conocer y obtengo este trabajo de la siguiente manera:

Combinando con linux command ln , podemos hacer algo mucho más simple:

 1. cd Proj/Client 2. ln -s ../Common ./ 3. cd Proj/Server 4. ln -s ../Common ./ 

Y ahora, si desea importar un some_stuff del archivo: Proj/Common/Common.py a su archivo: Proj/Client/Client.py , de esta manera:

 # in Proj/Client/Client.py from Common.Common import some_stuff 

Y, lo mismo se aplica a Proj/Server , también funciona para el proceso setup.py , una misma pregunta que se discute aquí , ¡espero que ayude!

El método de importación predeterminado ya es “relativo”, desde PYTHONPATH. PYTHONPATH es, por defecto, para algunas bibliotecas del sistema junto con la carpeta del archivo fuente original. Si ejecuta con -m para ejecutar un módulo, el directorio actual se agrega a PYTHONPATH. Entonces, si el punto de entrada de su progtwig está dentro de Proj, el uso de la import Common.Common debería funcionar dentro de Server.py y Client.py.

No hagas una importación relativa. No funcionará como quieres que lo haga.