2013-03-06 18 views
5

Chciałbym mieć strukturę modułów/pakiety, na przykład następujący:moduły Pythona konwencji hierarchia nazewnictwa

/__init__.py 
/mymodule.py 
/mymodule/ 
/mymodule/__init__.py 
/mymodule/submodule.py 

a następnie za pomocą modułów takich jak:

import mymodule 
import mymodule.submodule 

Ale wydaje się, że plik "mymodule. py "konflikty z" "mymodule" katalogu.

Jaka jest tutaj właściwa konwencja nazewnictwa?

Dzięki.

Odpowiedz

11

Jeśli chcesz, aby pakiet, musisz zrozumieć, jak Python tłumaczy nazwy plików do nazw modułów.

Plik będzie dostępny jako mymodule, zakładając, że interpreter znajdzie go w katalogu w ścieżce wyszukiwania w języku Python. Jeśli korzystasz z systemu plików niewrażliwego na wielkość liter, możesz również importować go przy użyciu wielkich liter (ale powinieneś unikać takiego zachowania zależnego od systemu).

Pakiet jest katalogiem zawierającym plik __init__.py. Ostatnio pojawił się ruch, aby umożliwić pakiety bez tych plików, ale zamierzam zignorować ten mniej powszechny przypadek dla tej odpowiedzi. Pakiet staje się modułem wewnątrz Pythona, jego kod pochodzi z pliku __init__.py. Plik mypackage/__init__.py można zaimportować jako mypackage.

Plik __init__.py nie ma żadnego znaczenia bezpośrednio w ścieżce wyszukiwania w języku Python (cóż, prawdopodobnie można zaimportować moduł __init__, ale jest to prawdopodobnie zły pomysł).

więc do sytuacji, oto odpowiedni układ plików:

toplevel/ 
    mymodule/ 
     __init__.py  # put code here for mymodule 
     submodule.py # put code here for mymodule.submodule 

toplevel Tylko Folder powinien znajdować się w ścieżce wyszukiwania Pythona.

+0

Widziałem, jak Python zniechęcił ludzi do umieszczania znaczącego kodu w 'mymodule/__ init __. Py' chociaż, np. [Alex Martelli] (http://stackoverflow.com/a/2361278/188535), co wydaje się być sprzeczne z tym. (Nie koniecznie muszę się z tym zgodzić ...) – detly

+2

To prawda. Bardziej popularnym stylem byłoby umieszczenie rzeczywistego kodu 'mymodule' w nieudokumentowanym module podległym, a następnie zaimportowanie publicznego interfejsu API do' __init __. Py'. – Blckknght

+0

dziękuję za odpowiedź informacyjną. Szkoda, że ​​pyton potrzebuje takich brudnych hacków, żeby zrobić coś oczywistego. –

4

Masz do czynienia z package. Struktura pakietu powinno być to:

/some-parent-directory # This needs to be on sys.path 
    /mymodule # This is not really a module - it's a package 
     __init__.py # import mymodule 
     # init is loaded when you `import mymodule` or anything below it 
     some.py # import mymodule.some 
     implementation.py # import mymodule.implementation 
     files.py # import mymodule.files 
     /submodule 
      __init__.py # import mymodule.submodule 
      # init is loaded when you `import mymodule.submodule` or anything below it 
      submodule_impl.py # import mymodule.submodule.submodule_impl 
      goes.py # import mymodule.submodule.goes 
      here.py # import mymodule.submodule.here 

Dopóki rodzic katalog jest na sys.path będzie można zadzwonić import mymodule lub from mymodule.submodule import something bez problemu.

Jeśli chcesz coś być dostępne z poziomu głównego pakietu (tj. Np. from mymodule import SomeItem lub z sub-pakietu from mymodule.submodule import AnotherItem), a następnie można zaimportować go do odpowiedniego __init__.py pliku.

Załóżmy na przykład, że klasa CustomClass zdefiniowana w module submodule_impl.py może być importowana bezpośrednio z submodule. Twój submodule/__init__.py musiałby zawierać następujące elementy:

from .submodule_impl import CustomClass 

Wtedy będzie można importować CustomClass bezpośrednio od submodule (tj from mymodule.submodule import CustomClass)

Powiązane problemy