2011-01-11 9 views
22
stuff/ 
    __init__.py 
    mylib.py 
    Foo/ 
     __init__.py 
     main.py 
     foo/ 
      __init__.py 
      script.py 

script.py quiere importar mylib.pycómo llevar a cabo la importación relativa en pitón

Esto es sólo un ejemplo, pero en realidad sólo quiero hacer una importación relativa de un módulo en un directorio padre. He intentado varias cosas y sale este error ...

Attempted relative import beyond toplevel package

He leído en alguna parte que la secuencia de comandos desde donde se inicia el programa no debe en el paquete, y yo trataba de modificar la estructura para que como tal ...

stuff/ 
    mylib.py 
    foo.py // equivalent of main.py in above 
    foo/ 
     __init__.py 
     script.py 

pero tengo el mismo error.

¿Cómo puedo lograr esto? ¿Es este un enfoque adecuado?

Editar: En Python 2

Respuesta

28

Después de tocar el violín con él un poco más, me di cuenta de cómo configurarlo, y por el bien de la especificidad no voy a utilizar foo nombres de barras Mi directorio del proyecto se configura como ...

tools/ 
    core/ 
     object_editor/ 
      # files that need to use ntlib.py 
      editor.py # see example at bottom 
      __init__.py 
     state_editor/ 
      # files that need to use ntlib.py 
      __init__.py 
     ntlib.py 
     __init__.py # core is the top level package 
    LICENSE 
    state_editor.py # equivalent to main.py for the state editor 
    object_editor.py # equivalent to main.py for the object editor 

Una línea de object_editor.py parece ...

from core.object_editor import editor 

Una línea en editor.py ... parece

from .. import ntlib 

o alternativamente

from core import ntlib 

La clave es que en el ejemplo que di en la pregunta, el script "principal" se estaba ejecutando desde dentro del paquete. Una vez que lo moví, creé un paquete específico (core) y moví la biblioteca que quería que los editores compartieran (ntlib) en ese paquete, todo era cachondo-dory.

+1

Lo tienes. Lo que sucede es que no puede usar importaciones relativas del script que está ejecutando desde la línea de comando, por lo que debería estar en el nivel superior de la organización, haciendo referencia a las cosas que están debajo. –

+0

¿Por qué el script "principal" se estaba ejecutando desde dentro del paquete causaba los problemas? – Bin

1

import ..foo..stuff.mylib debería estar bien

EDITAR se quitó la extensión

+4

no creo que esto es una sintaxis válida. – random

+0

'from ..foo..stuff.mylib import whatever' should ok – tekknolagi

+0

import sys sys.path.append() import Bar
tekknolagi

10

aunque siempre "cosas" no está en su PATH pitón que tienes otra opción de agregar el camino .

Si conoce el nivel de su script.py de cosas que puede hacer por ejemplo:

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

¿Está esto documentado en alguna parte? No es que no te crea, pero en el caso de solo querer decir "hey import from 2 directories up" es necesario modificar la ruta del sistema, tengo que verlo con mis propios ojos. – random

+0

Esto es lo que suelo terminar haciendo, aunque sea por despecho. – jdm

+0

No diría que está exactamente documentado de esta manera. aunque usé esto varias veces yo mismo. Solo modificará la ruta del sistema para ejecutar el script de python, no de forma global en el sistema de todos modos. Creo que no deberías molestarte. : P –

1

Desde el PEP parece que no puede utilizar una importación correspondientes a la importación de un archivo que no se empaqueta.

lo que sería necesario añadir un __init__.py a cosas y cambiar sus importaciones a algo así como from .mylib import *

Sin embargo, el PEP parece que no tiene en cuenta para mantener mibiblioteca envasados ​​en un módulo. Por lo tanto, es posible que deba cambiar la forma en que llama a las funciones de su biblioteca.

Otra alternativa es mover mibiblioteca en un sub-paquete e importarlo como from .libpackage import mylib

7

Estoy ejecutando Python 3.4.2 en Windows 7 y me arranqué el pelo por esto.

Cuando se ejecuta cualquiera de éstos:

python -m unittest python -m unittest descubrir

... que tendría la 'importación relativa Intento allá paquete de nivel superior' error.

Para mí, la solución estaba cayendo el "..." en mi [test_stock.py]. La línea era: de importación ..stock de

lo cambió a: a partir de la importación de la

.. y funciona.

estructura de carpetas:

C:\ 
    | 
    +-- stock_alerter 
      | 
      +-- __init__.py 
      +-- stock.py 
      | 
      \-- tests 
        | 
        +-- __init__.py 
        \-- test_stock.py 
+0

Su solución funciona pero no puedo entender por qué ... Además, Pycharm se está volviendo loco con esto y resalta en rojo la afirmación –

+0

Funciona porque ya no es una importación relativa cuando elimina el '..'. En cambio, es una importación absoluta. PyCharm utilizará el directorio de origen del proyecto para resolverlo, lo que significa que puede necesitar agregar manualmente un directorio en la configuración del proyecto para ayudarlo a resolver las importaciones. – meowsqueak

Cuestiones relacionadas