Czy ktoś mógłby mi zapewnić dobry sposób na import całego katalogu modułów?
Mam taką strukturę:
/Foo
bar.py
spam.py
eggs.py
Próbowałem po prostu przekonwertować go na pakiet, dodając __init__.py
i wykonując, from Foo import *
ale nie działało to tak, jak chciałem.
python
python-import
Evan Fosmark
źródło
źródło
Odpowiedzi:
Wyświetl wszystkie
.py
pliki python ( ) w bieżącym folderze i umieść je jako__all__
zmienne w__init__.py
źródło
if not os.path.basename(f).startswith('_')
lub przynajmniejif not f.endswith('__init__.py')
do końca listyos.path.isfile(f)
jestTrue
. To odfiltrowałoby zepsute dowiązania symboliczne i katalogi, takie jaksomedir.py/
(przypadek, przyznaję, ale nadal ...)from . import *
po ustawieniu__all__
jeśli chcesz Submoduły być dostępne przy użyciu.
(npmodule.submodule1
,module.submodule2
itp).Dodaj
__all__
zmienną do__init__.py
zawierającą:Zobacz także http://docs.python.org/tutorial/modules.html
źródło
os.listdir()
, niektóre filtrowanie, usuwanie.py
rozszerzenia i__all__
.moduleName.varName
. Ref. stackoverflow.com/a/710603/248616Aktualizacja w 2017 r .: prawdopodobnie chcesz
importlib
zamiast tego użyć .Zrób katalog Foo pakietem, dodając
__init__.py
. W tym__init__.py
dodaj:Ponieważ chcesz, aby był dynamiczny (co może, ale nie musi być dobrym pomysłem), wypisz wszystkie pliki py z list dir i zaimportuj je za pomocą czegoś takiego:
Następnie z kodu wykonaj następujące czynności:
Możesz teraz uzyskać dostęp do modułów za pomocą
itp.
from Foo import *
nie jest dobrym pomysłem z kilku powodów, w tym z powodu konfliktów nazw i utrudniania analizy kodu.źródło
__import__
hackish, myślę, że lepiej byłoby dodać nazwy,__all__
a następnie umieścićfrom . import *
na dole skryptu__import__
nie jest do ogólnych zastosowań, jest używany przezinterpreter
, użyjimportlib.import_module()
zamiast tego.from . import eggs
itd w__init__.py
przed Pythonie mógł importować. Ze tylkoimport eggs
ja dostaćModuleNotFoundError: No module named 'eggs'
podczas próbyimport Foo
wmain.py
się w katalogu powyżej.Rozwijając odpowiedź Mihaila, uważam, że niehackerski sposób (jak w przypadku braku bezpośredniej obsługi ścieżek plików) jest następujący:
__init__.py
plik podFoo/
Dostaniesz:
źródło
RuntimeWarning
wiadomości mogą być również unikać nie używając w ogóle full_package_name:importer.find_module(package_name).load_module(package_name)
.RuntimeWarning
mogą być również unikać błędów (w niewątpliwie brzydki sposób) importując dominującej (AKA dirname). Jednym ze sposobów na to jest -if dirname not in sys.modules: pkgutil.find_loader(dirname).load_module(dirname)
. Oczywiście działa to tylko wtedy, gdydirname
jest ścieżką względną jednoskładnikową; bez cięć. Osobiście wolę podejście Artfunkela polegające na użyciu podstawowej nazwy_pakietu.Python, dołącz wszystkie pliki do katalogu:
Dla początkujących, którzy po prostu nie mogą go uruchomić i potrzebują trzymania się za ręce.
Utwórz folder / home / el / foo i utwórz plik
main.py
w katalogu / home / el / foo Umieść tam ten kod:Utwórz katalog
/home/el/foo/hellokitty
Utwórz plik
__init__.py
poniżej/home/el/foo/hellokitty
i umieść tam kod:Utwórz dwa pliki Pythona:
spam.py
iham.py
poniżej/home/el/foo/hellokitty
Zdefiniuj funkcję w spam.py:
Zdefiniuj funkcję wewnątrz ham.py:
Uruchom:
źródło
import *
jest uważane za złą praktykę kodowania w języku Python. Jak to zrobić bez tego?Sam zmęczyłem się tym problemem, więc napisałem pakiet o nazwie automodinit, aby go naprawić. Możesz go pobrać ze strony http://pypi.python.org/pypi/automodinit/ .
Użycie jest takie:
automodinit
pakiet w swoichsetup.py
zależnościach.Otóż to! Odtąd importowanie modułu ustawi __all__ na listę plików .py [co] w module, a także będzie importować każdy z tych plików tak, jakbyś wpisał:
Dlatego efekt „z importu M *” odpowiada dokładnie „importowi M”.
automodinit
chętnie korzysta z archiwów ZIP i dlatego jest bezpieczny dla ZIP.Niall
źródło
Wiem, że aktualizuję dość stary post i próbowałem go użyć
automodinit
, ale dowiedziałem się, że proces instalacji dla Python3 jest uszkodzony. Tak więc, w oparciu o odpowiedź Lucy, znalazłem prostszą odpowiedź - która może nie działać z .zip - na ten problem, więc pomyślałem, że powinienem ją tutaj udostępnić:w
__init__.py
module odyourpackage
:oraz w ramach innego pakietu poniżej
yourpackage
:Następnie załadujesz wszystkie moduły umieszczone w pakiecie, a jeśli napiszesz nowy moduł, zostanie on również zaimportowany automatycznie. Oczywiście, używaj tego rodzaju rzeczy ostrożnie, z wielkimi mocami wiąże się wielka odpowiedzialność.
źródło
źródło
Zetknąłem się również z tym problemem i to było moje rozwiązanie:
Ta funkcja tworzy plik (w podanym folderze) o nazwie
__init__.py
, który zawiera__all__
zmienną, która przechowuje każdy moduł w folderze.Na przykład mam folder o nazwie,
Test
który zawiera:Więc w skrypcie chcę, aby moduły zostały zaimportowane, napiszę:
Spowoduje to zaimportowanie wszystkiego,
Test
a__init__.py
plik wTest
będzie teraz zawierać:źródło
Przykład Anuraga z kilkoma poprawkami:
źródło
Odpowiedź Anurag Uniyal z sugerowanymi ulepszeniami!
źródło
Zobacz, jakie są Twoje
__init__.py
definicje__all__
. Moduły - pakiety doc mówiźródło
To najlepszy sposób, jaki do tej pory znalazłem:
źródło
Korzystanie
importlib
jedyną rzeczą, którą muszę dodać jestźródło
error: Type of __all__ must be "Sequence[str]", not "List[Module]"
. Definiowanie__all__
nie jest wymagane, jeśliimport_module
stosowane jest takie podejście.Spójrz na moduł pkgutil ze standardowej biblioteki. Pozwoli ci to robić dokładnie to, co chcesz, o ile masz
__init__.py
plik w katalogu.__init__.py
Plik może być pusty.źródło
Stworzyłem do tego moduł, który nie polega na
__init__.py
(ani na żadnym innym pliku pomocniczym) i każe mi pisać tylko następujące dwie linie:Zapraszam do ponownego użycia lub współtworzenia: http://gitlab.com/aurelien-lourot/importdir
źródło
Wystarczy zaimportować je za pomocą importlib i dodać je
__all__
(add
akcja jest opcjonalna) w rekursie w__init__.py
pakiecie.źródło
py
Gdy
from . import *
nie jest wystarczająco dobry, jest to poprawa w stosunku do odpowiedzi Teda . W szczególności zastosowanie__all__
tego podejścia nie jest konieczne.Należy pamiętać, że
module_name not in globals()
ma to na celu uniknięcie ponownego importowania modułu, jeśli jest już zaimportowany, ponieważ może to spowodować ryzyko cyklicznego importu.źródło