2012-09-20 7 views
5

Używam __init__.py do uruchamiania czeków, gdy robię from myprojects.something import blabla.Używanie __init__.py

Dzisiaj zacząłem używać pyzmq i chciałem zobaczyć, co dzieje się za kulisami. Przeglądałem kod w github i znalazłem (dla mnie) dziwne użycie __init__.py, którego nie potrafię sobie wytłumaczyć.

Na przykład zmq/core/__init__.py. Jaki jest sens dodania wartości zmq.core.__all__ o wartości zmq.core.constants, zmq.core.error, zmq.core.message, etc.?

W zmq/__init__.py widzę na końcu

__all__ = ['get_includes'] + core.__all__ 

gdzie get_includes jest funkcją, która w zasadzie zwraca listę z katalogu modułu i katalogu utils w katalogu nadrzędnego.

Jaki jest sens? Co osiągnięto, osiągając __init.py__?

Odpowiedz

11

Numer __all__ dotyczy sytuacji, gdy ktoś wykonuje from module import * jako dokumentację here.

Jedynym rozwiązaniem jest podanie przez autora pakietu jawnego indeksu pakietu. Instrukcja importu używa następującej konwencji : jeśli kod pakietu __init__.py definiuje listę o nazwie __all__, przyjmuje się, że jest to lista nazw modułów, które powinny zostać zaimportowane, gdy napotkany zostanie import pakietu *. Od autora pakietu do aktualizowanie tej listy jest możliwe po opublikowaniu nowej wersji pakietu . Autorzy pakietów mogą również zdecydować o nieobsługiwaniu tego, jeśli nie zobaczą zastosowania do importowania * z ich pakietu. Dla przykład plik sounds/effects/__init__.py mogłyby zawierać następujący kod:

__all__ = ["echo", "surround", "reverse"] 

oznaczałoby to, że from sound.effects import * będzie importować trzy nazwane submodules pakietu dźwięku.

Jedno użycie dla __all__ to narzędzie dla twórców pakietów, które pozwala im na zorganizowanie pakietu w sposób, który działa na ich korzyść, zapewniając wygodę użytkownikom. W szczególności w przypadku pyzmq, pozwala pisać kod, takich jak:

import zmq 
print zmq.zmq_version() 

Zamiast korzystać z pełnej przerywaną nazwę modułu:

print zmq.core.version.zmq_version() 

Pakiet projektanci pyzmq korzystania __all__ promowanie elementy przestrzeni nazw z zagnieżdżonych modułów do najwyższego poziomu ich przestrzeni nazw, aby użytkownik nie przejmował się strukturą pakietu.

+0

Przeczytałem tę część dokumentacji przed pytaniem tutaj. Ale to nadal nie odpowiada na moje pytanie. Być może powinienem zapytać w inny sposób: I chociaż powodem używania 'od bla import ble 'było to, że kontrolowałeś swój obszar nazw, co oznacza, że ​​decydujesz, które symbole dodasz do swojej nazwy. – Pablo

+0

Tak jak w przeciwieństwie do C, użycie '# include' może spowodować kolizję z już zdefiniowanymi funkcjami, zmiennymi itp. Powinieneś zaimportować tylko te symbole, które naprawdę potrzebujesz. Chociaż czytałem gdzieś w dokumentacji Pythona, że ​​używanie 'from bla import *' nie było dobrym nawykiem. Jeśli tak, to po co w ogóle definiować '__ all__'? A w jaki sposób '__all__ = ['get_includes'] + core .__ all__' są oceniane podczas wykonywania' import * '? – Pablo

+1

from bla import * nie jest dobrym zwyczajem, ale niektóre moduły są ogólnie bezpieczne. Rutynowo robię z importu matematyki *. Dokumentacja tych modułów często wskazuje, że są one zaprojektowane tak, aby były używane w ten sposób i wspierają takie elementy, jak __all__, aby było nieco łatwiej. Ale od x import * jest coś, co należy stosować ostrożnie i tylko z pakietami, o których wiesz, że nie spowoduje to problemu. – TimothyAWiseman

Powiązane problemy