Вопрос

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

script.py хочет импортировать mylib.py

Это просто пример, но на самом деле я просто хочу сделать относительный импорт модуля в родительском каталоге. Я пробовал разные вещи и получите эту ошибку ...

Attempted relative import beyond toplevel package

Я прочитал где-то, что скрипт откуда начинается программа, не должна в пакете, и я попытался изменить структуру для того, что так ...

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

Но получите ту же ошибку.

Как я могу сделать это? Это даже адекватный подход?

Редактировать: в Python 2

Это было полезно?

Решение

После возобновления с ним немного больше, я понял, как его настроить, и ради специфичности я не буду использовать имена BAR FO. Мой каталог проекта установлен как ...

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

Линия object_editor.py выглядит как...

from core.object_editor import editor

Линия editor.py выглядит как...

from .. import ntlib

или в качестве альтернативы

from core import ntlib

Ключ заключается в том, что в этом примере я дал в вопросе, в рамках в пределах пакета был запущен «главный» скрипт. Как только я переехал, создал определенный пакет (core) и переместил библиотеку, которую я хотел редакторов поделиться (ntlib) в этот пакет, все было склонны-дори.

Другие советы

Хотя как длинные «вещи» не в вашем пути Python, у вас нет выбора, чем добавление пути.

Если вы знаете уровень вашего Script.py из вещей, вы можете сделать, например:

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

Я бегаю Python 3.4.2 на Windows 7 и оторваю волосы над этим.

При запуске любого из них:

Python -M Unittest Python -M Unittest Discover

... Я бы получил попытку относительного импорта за пределы ошибки Toplevel Package.

Для меня решение опускало «..» в моем [test_stock.py]. Линия была: от импортных запасов.

Изменил его на: от наличия импортных запасов

.. и это работает.

Структура папки:

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

import ..foo..stuff.mylib должно быть хорошо

Редактировать снял расширение

От Пеп Похоже, что вы не можете использовать относительный импорт для импорта файла, который не упакован.

Так что вам нужно будет добавить __init__.py надовать и изменить свой импорт на что-то вроде from .mylib import *

Тем не менее, PEP, кажется, не приносит пособие, чтобы MyLib упаковывать в модуле. Таким образом, вам может потребоваться изменить, как вы называете свои функции библиотеки.

Еще одна альтернатива - переместить MyLib в подраздел и импортировать его как from .libpackage import mylib

Если вы на Linux или, возможно, похожего * NIX, вы можете взломать это с SymLinks.

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

Это, вероятно, не хороший шаблон, чтобы следовать.

В моем случае я выбрал это, потому что у меня были несколько исполняемых файлов, зависящих от одной и той же библиотеки, которая должна была быть введена в отдельные каталоги.

Реализация новых исполняемых испытаний не должна требовать тестового писателя, чтобы оказать глубокое понимание импорта Python.

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


Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top