Domanda

stuff/
    __init__.py
    mylib.py
    Foo/
        __init__.py
        main.py
        foo/
            __init__.py
            script.py

script.py vuole importare mylib.py

Questa è solo un esempio, ma in realtà voglio solo fare un'importazione parente di un modulo in una directory padre. Ho provato varie cose e ottengo questo errore ...

Attempted relative import beyond toplevel package

Ho letto da qualche parte che lo script dal punto in cui il programma si avvia non dovrebbero nel pacchetto, e ho cercato di modificare la struttura per quello in questo modo ...

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

ma ha ottenuto lo stesso errore.

Come posso fare questo? E 'questo anche un approccio adeguato?

Edit: In Python 2

È stato utile?

Soluzione

Dopo giocherellare con un po 'di più, ho capito come impostare l'alto, e per amore di specificità non userò i nomi foo bar. La mia directory del progetto si configura come ...

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 linea negli sguardi object_editor.py come ...

from core.object_editor import editor

Una linea negli sguardi editor.py come ...

from .. import ntlib

oppure

from core import ntlib

La chiave è che nell'esempio ho dato in questione, lo script "principale" è stato eseguito da all'interno del pacchetto. Una volta mi sono trasferito fuori, ha creato un pacchetto specifico (core), e si è trasferito la biblioteca ho voluto i redattori alla quota (ntlib) in quel pacchetto, tutto era rose e fiori.

Altri suggerimenti

anche se il più a lungo "roba" non è nel PATH pitone hai altra scelta che aggiungere il percorso.

Se si conosce il livello della vostra script.py da cose che si può fare ad esempio:

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

Io corro Python 3.4.2 su Windows 7 e strappò i capelli fuori su questo.

Quando si esegue uno di questi:

  

python -m unittest   python -m unittest scoprire

... Vorrei ottenere il 'importazione relativa Tentativo di là pacchetto toplevel' errore.

Per me, la soluzione era caduta la ".." nel mio [test_stock.py]. La linea era:   dall'importazione ..stock della

cambiato in:   a magazzino di importazione della

.. e funziona.

struttura di cartelle:

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

import ..foo..stuff.mylib dovrebbe essere ok

EDIT tolse l'estensione

PEP appare che non è possibile utilizzare una di importazione rispetto ad importare un file che non è confezionato.

Quindi, si avrebbe bisogno di aggiungere un __init__.py di roba e cambiare le importazioni in qualcosa di simile from .mylib import *

Tuttavia, il PEP sembra fare alcuna indennità per mylib mastio confezionato in un modulo. Così potrebbe essere necessario per cambiare il modo di chiamare le funzioni di libreria.

Un'altra alternativa è quella di spostare mylib in un subpackage e importarlo come from .libpackage import mylib

Se siete su Linux o forse un simile * nix, è possibile incidere questo con collegamenti simbolici.

stuff/
    mylib.py
    foo.py // equivalent of main.py in above
    foo/
        script.py
        mylib.py  ->  ../mylib.py
    foo2/
        script2.py
        mylib.py  ->  ../mylib.py

Questo non è probabilmente un buon modello da seguire.

Nel mio caso ho optato per questo perché ho avuto più eseguibili dipendenti dalla stessa libreria che aveva bisogno di essere messo in directory separate.

Realizzazione di nuovi test eseguibili non dovrebbero richiedere lo scrittore prova di avere una profonda comprensione delle importazioni pitone.

tests/
    common/
        commonlib.py
    test1/
        executable1.py
        executable2.py
        commonlib.py -> ../common/commonlib.py
    test2/
        executable1.py
        executable2.py
        commonlib.py -> ../common/commonlib.py


Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top