Jak poprawnie używać importu względnego lub bezwzględnego w modułach Pythona?
Użycie względnych importów w Pythonie ma jedną wadę, nie będziesz mógł już uruchamiać modułów jako samodzielnych, ponieważ otrzymasz wyjątek: ValueError: Attempted relative import in non-package
# /test.py: just a sample file importing foo module
import foo
...
# /foo/foo.py:
from . import bar
...
if __name__ == "__main__":
pass
# /foo/bar.py: a submodule of foo, used by foo.py
from . import foo
...
if __name__ == "__main__":
pass
Jak zmodyfikować przykładowy kod, aby móc wykonać wszystkie: test.py
, foo.py
i bar.py
Szukam rozwiązania, które działa z Pythonem 2.6+ (w tym 3.x).
6 answers
Po pierwsze, zakładam, że zdajesz sobie sprawę z tego, co napisałeś, doprowadziłoby do okrągłego problemu z importem, ponieważ Foo importuje pasek i viceversa; spróbuj dodać
from foo import bar
To test.py i zobaczysz, że się nie powiedzie. Przykład musi zostać zmieniony, aby zadziałał.
Więc to, o co prosisz, to tak naprawdę powrót do importu bezwzględnego, gdy import względny nie powiedzie się; w rzeczywistości, jeśli wykonujesz foo.py lub bar.py jako główny moduł, pozostałe moduły będą po prostu leżeć na poziomie głównym, a jeśli dzielą nazwę z inny moduł w systemie, który zostanie wybrany, zależy od kolejności w sys./ align = "left" / Ponieważ bieżący katalog jest zwykle pierwszym, lokalne moduły będą wybierane, jeśli są dostępne - tzn. jeśli masz 'os.py' plik w bieżącym katalogu roboczym, zostanie wybrany zamiast wbudowanego.
Możliwą sugestią jest:
Foo.py
try:
from . import bar
except ValueError:
import bar
if __name__ == "__main__":
pass
Bar.py:
if __name__ == "__main__":
pass
Przy okazji wywołanie skryptów z odpowiedniej pozycji jest zwykle sposobem lepszym.
python -m foo.bar
Jest to chyba najlepszy sposób. Ten uruchamia moduł jako skrypt .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-25 22:14:23
Możesz po prostu zacząć 'uruchamiać Moduły jako samodzielne' w nieco inny sposób:
Zamiast:
python foo/bar.py
Użycie:
python -mfoo.bar
Oczywiście plik foo/__init__.py
musi być obecny.
Zwróć również uwagę, że masz Okrężną zależność między foo.py
i bar.py
– to nie zadziała. To chyba pomyłka w twoim przykładzie.
Update: wygląda na to, że działa również doskonale, aby użyć tego jako pierwszej linii foo/bar.py
:
#!/usr/bin/python -mfoo.bar
Wtedy możesz wykonać skrypt bezpośrednio w systemach POSIX.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-01 12:29:41
Porzuć względny import: powinieneś myśleć o swojej przestrzeni nazw pakietów jako o przestrzeni globalnej.
Sztuką tworzenia tego smacznego jest odpowiednie edytowanie sys.path
. Oto coś do przemyślenia:
# one directory up _root_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) sys.path.insert(0, _root_dir)for now
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-08 19:58:55
Potrzebujesz __init__.py
w każdym folderze.
Względny import działa tylko wtedy, gdy:
python test.py
Test.py przywóz foo.py oraz foo.py może względnie importować cokolwiek z folderu test.py i wyżej.
You can ' t do:
cd foo
python foo.py
python bar.py
To nigdy nie zadziała.
Możesz spróbować sys./ align = "left" / Dołącz lub sys./ align = "left" / Wstaw rozwiązanie ale zepsujesz ścieżki i będziesz miał problemy z F = open (nazwa pliku).Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-28 01:59:21
Dlaczego po prostu nie umieścić "main" w innym pliku .py?
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-06 02:55:52
Jak na razie jedynym rozwiązaniem, jakie znalazłem, było nieużywanie w ogóle importu względnego.
Ze względu na obecne ograniczenia, zastanawiam się, kiedy ktoś powinien używać względnych importów w Pythonie.
Na wszystkich konfiguracjach, które używałem sys.path
zawiera bieżący katalog jako pierwszy argument, więc po prostu użyj import foo
zamiast from . import foo
, ponieważ zrobi to samo.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-08 19:58:39