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

script.py chce importować mylib.pyJak osiągnąć względną przywozu w Pythonie

To tylko przykład, ale tak naprawdę po prostu chcę zrobić względną importu modułu w katalogu nadrzędnego. Próbowałem różnych rzeczy i dostać ten błąd ...

Attempted relative import beyond toplevel package

Czytałem gdzieś, że skrypt skąd rozpoczyna program nie powinien się w pakiecie, a ja starałem modyfikując strukturę, że tak jak ...

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

ale dostałem ten sam błąd.

Jak mogę to zrobić? Czy to nawet odpowiednie podejście?

Edit: W Pythonie 2

Odpowiedz

28

Po błahy z nim nieco więcej, zdałem sobie sprawę, jak to ustawić, a ze względu na specyficzność nie będę używać foo nazwy słupków. Mój katalog projekt jest skonfigurowany jako ...

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 

Linia w object_editor.py wygląda jak ...

from core.object_editor import editor 

Linia w editor.py wygląda jak ...

from .. import ntlib 

lub alternatywnie:

from core import ntlib 

Kluczem jest to, że w przykładzie, który podałem w pytaniu, skrypt "główny" był uruchamiany z pakietu. Kiedy go przeniosłem, utworzyłem specjalny pakiet (core) i przeniosłem bibliotekę, którą chciałem udostępnić redaktorom (ntlib) do tego pakietu, wszystko było hunky-dory.

+1

Masz to. Co się dzieje, że nie można używać importów względnych ze skryptu, który uruchamiasz z wiersza poleceń, więc powinien znajdować się na najwyższym poziomie organizacji, odwołując się do rzeczy poniżej. –

+0

Dlaczego "główny" skrypt został uruchomiony z poziomu pakietu powodują problemy? – Bin

1

import ..foo..stuff.mylib powinno być ok

EDIT zdjął rozszerzenie

+4

nie sądzę, to jest prawidłowa składnia. – random

+0

'from ..foo..stuff.mylib import cokolwiek' powinno być OK – tekknolagi

+0

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

10

choć jak długo "rzeczy" nie jest w python PATH masz innego wyboru, niż dodanie ścieżki .

Jeśli znasz poziom swojej script.py z rzeczy można zrobić na przykład:

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

Czy to gdzieś dokumentuje? Nie dlatego, że ci nie wierzę, ale w przypadku, gdy chcę tylko powiedzieć "hej import z 2 katalogów w górę" wymaga modyfikacji ścieżki systemu, muszę to zobaczyć na własne oczy. – random

+0

To jest to, co zwykle robię, choćby ze złości. – jdm

+0

Nie powiedziałbym, że jest to dokładnie udokumentowane. chociaż sam wielokrotnie to wykorzystałem. Po prostu zmodyfikuje ścieżkę systemową dla uruchomionego skryptu Pythona, a nie globalnie w systemie. Myślę, że nie powinieneś mieć nic przeciwko. : P –

1

Z PEP wydaje się, że nie można korzystać z względną import zaimportować plik, który nie jest spakowany.

Więc trzeba by dodać __init__.py do rzeczy i zmienić swoje importu do czegoś jak from .mylib import *

Jednak PEP wydaje się nie mieć dodatek do utrzymania myLib pakowane w module. Być może będziesz musiał zmienić sposób wywoływania funkcji biblioteki.

Inną alternatywą jest przeniesienie myLib w podpakiecie i zaimportować go jako from .libpackage import mylib

7

Używam Python 3.4.2 na Windows 7 i rozdarłem sobie włosy.

Podczas uruchamiania jednego z nich:

python -m unittest python -m unittest odkryć

... chciałbym uzyskać 'próba względną importu poza pakietem, będąc w głównym' błędzie.

Dla mnie rozwiązaniem było zrzucenie ".." w moim [test_stock.py]. Linia była: od importu ..stock magazynie

zmienił go do: od importu Vectors

.. i to działa.

struktura folderów:

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

Twoje rozwiązanie działa, ale nie mogę zrozumieć, dlaczego ... Plus, Pycharm szaleje z tym i czerwone podkreślenie oświadczenie –

+0

Działa, ponieważ nie jest już względny import po usunięciu '..'. Zamiast tego jest to absolutny import. PyCharm użyje katalogu źródłowego projektu, aby go rozwiązać, co oznacza, że ​​konieczne może być ręczne dodanie katalogu w ustawieniach projektu, aby pomóc w rozwiązaniu importu. – meowsqueak

Powiązane problemy