2009-07-29 8 views
11

Załóżmy, że mam następującą strukturę:Importowanie plików w Pythonie z __init__.py

app/ 
    __init__.py 
    foo/ 
    a.py 
    b.py 
    c.py 
    __init__.py 

a.py, b.py i c.py pewne wspólne przywozu (rejestrowania, os, re, etc). Czy jest możliwe zaimportowanie tych trzech lub czterech wspólnych modułów z pliku __init__.py, więc nie muszę ich importować w każdym z plików?

Edytuj: Moim celem jest uniknięcie konieczności importowania 5-6 modułów z każdego pliku i nie jest to związane ze względami wydajności.

+0

Jeśli chcesz to zrobić ze względu na wydajność, nie martw się - import już załadowanych modułów jest superszybki (proste wyszukiwanie na sys.modules). – efotinis

+0

Edytowane pytanie w celu wyjaśnienia moich motywów. –

+1

Podany rodzaj celu zmniejsza czytelność kodu, nie sądzisz? – Santa

Odpowiedz

11

Nie, muszą być umieszczone w przestrzeni nazw każdego modułu, więc musisz je jakoś zaimportować (chyba że podasz logging jako argument funkcji, co byłoby dziwnym sposobem na robienie rzeczy, delikatnie mówiąc).

Ale moduły są importowane tylko raz mimo to (a następnie umieścić do a, b, a c nazw), więc nie martw się o wykorzystują zbyt dużo pamięci lub coś podobnego.

Można oczywiście umieścić je w osobnym module i zaimportować że do każdego a, b, a c, ale to osobny moduł nadal musiałyby być importowane za każdym razem.

13

Można to zrobić za pomocą wspólnego pliku, takiego jak include.py, ale jest to niezgodne z zalecanymi praktykami, ponieważ wiąże się z importowaniem symboli wieloznacznych. Rozważmy następujące pliki:

app/ 
    __init__.py 
foo/ 
    a.py 
    b.py 
    c.py 
    include.py <- put the includes here. 
    __init__.py 

Teraz w a.py itp zrobić:

from include import * 

Jak wspomniano powyżej, nie jest to zalecane, ponieważ wieloznaczne-import są zniechęceni.

+7

+1 dla symboli wieloznacznych. Głupia konsystencja to hobgoblin małych umysłów. Niemożliwe jest grupowanie importu powiązanego w sensowny sposób to brodawka pytona; w związku z tym musi ulec zmianie. – g33kz0r

6

Tak, ale nie rób tego. Poważnie, nie rób tego. Ale jeśli nadal chcesz wiedzieć, jak to zrobić, by to wyglądać tak:

import __init__ 

re = __init__.re 
logging = __init__.logging 
os = __init__.os 

mówię nie zrobić to nie tylko dlatego, że jest brudny i bez sensu, ale również dlatego, że pakiet nie jest tak naprawdę powinien używać takiego __init__.py. To jest kod inicjujący pakiet.

+0

Nie powiedziałbym, że to bezcelowe. Niektóre rzeczy, które chcesz zastosować do całego kodu, np. 'z przyszłego importu unicode_literals'. Czy naprawdę muszę umieścić to w każdym pliku (a potem zapomnieć o niektórych, powodując trudne do znalezienia błędy)? – Timmmm