Co to jest init.py za co?
Do czego służy __init__.py
w katalogu źródłowym Pythona?
11 answers
To część pakietu. Oto dokumentacja.
Pliki
__init__.py
są wymagane, aby Python traktował katalogi jako zawierające Pakiety; ma to na celu uniemożliwienie katalogom o wspólnej nazwie, takim jakstring
, niezamierzonego ukrywania poprawnych modułów, które pojawią się później (głębiej) na ścieżce wyszukiwania modułów. W najprostszym przypadku__init__.py
może być tylko pustym plikiem, ale może również wykonać kod inicjalizacyjny dla pakietu lub ustawić zmienną__all__
, opisaną później.
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
2016-02-05 16:23:19
Pliki o nazwie __init__.py
są używane do oznaczania katalogów na dysku jako katalogów pakietów Pythona.
Jeśli masz pliki
mydir/spam/__init__.py
mydir/spam/module.py
I mydir
jest na twojej ścieżce, możesz zaimportować kod w module.py
jako
import spam.module
Lub
from spam import module
Jeśli usuniesz plik __init__.py
, Python nie będzie już szukał podmoduł w tym katalogu, więc próby zaimportowania modułu nie powiodą się.
Plik __init__.py
jest zwykle pusty, ale można go użyć do eksportu wybranych części pakietu pod więcej wygodna nazwa, funkcje wygody itp.
Biorąc pod uwagę powyższy przykład, zawartość modułu init może być dostępna jako
import spam
Na podstawie tego
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-03-28 16:01:34
Oprócz etykietowania katalogu jako pakietu Pythona i definiowania __all__
, __init__.py
pozwala na zdefiniowanie dowolnej zmiennej na poziomie pakietu. jest to często wygodne, jeśli pakiet definiuje coś, co będzie często importowane, w sposób podobny do API. Ten wzór Promuje przestrzeganie filozofii Pythonicznej "płaskie jest lepsze niż zagnieżdżone".
Przykład
Oto przykład z jednego z moich projektów, w którym często importuję sessionmaker
o nazwie Session
do wejdź w interakcję z moją bazą danych. Napisałem pakiet "baza danych" z kilkoma modułami:
database/
__init__.py
schema.py
insertions.py
queries.py
Mój __init__.py
zawiera następujący kod:
import os
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
engine = create_engine(os.environ['DATABASE_URL'])
Session = sessionmaker(bind=engine)
Ponieważ definiuję Session
tutaj, mogę rozpocząć nową sesję używając składni poniżej. Kod ten byłby taki sam, wykonywany z wewnątrz lub poza katalogiem pakietów "database".
from database import Session
session = Session()
Oczywiście jest to mała wygoda -- alternatywą byłoby zdefiniowanie Session
w nowym Pliku jak "create_session.py" w moim pakiecie bazy danych i rozpocznij nowe sesje używając:
from database.create_session import Session
session = Session()
Czytaj dalej
Jest dość ciekawy wątek dotyczący odpowiednich zastosowań __init__.py
tutaj:
Http://www.reddit.com/r/Python/comments/1bbbwk/whats_your_opinion_on_what_to_include_in_init_py/
Większość uważa, że pliki powinny być bardzo cienkie, aby uniknąć naruszania filozofii "explicit is better than implicit".
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
2013-09-24 17:55:49
Istnieją 2 główne powody __init__.py
-
Dla wygody: inni użytkownicy nie będą musieli znać dokładnej lokalizacji Twoich funkcji w hierarchii pakietów.
your_package/ __init__.py file1.py/ file2.py/ ... fileN.py # in __init__.py from file1 import * from file2 import * ... from fileN import * # in file1.py def add(): pass
Wtedy inni mogą wywołać add () przez
from your_package import add
Bez znajomości file1, jak
from your_package.file1 import add
-
Jeśli chcesz, aby coś zostało zainicjowane; na przykład, logowanie (które powinno być umieszczone na najwyższym poziomie):
import logging.config logging.config.dictConfig(Your_logging_config)
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-01-02 14:29:05
Plik __init__.py
sprawia, że Python traktuje katalogi zawierające go jako moduły.
Co więcej, jest to pierwszy plik, który zostanie załadowany do modułu, więc możesz go użyć do wykonania kodu, który chcesz uruchomić za każdym razem, gdy moduł jest ładowany, lub określić podmoduły, które mają być eksportowane.
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
2009-01-15 20:22:58
Od wersji Pythona 3.3, __init__.py
nie jest już wymagane definiowanie katalogów jako importowalnych pakietów Pythona.
Sprawdź PEP 420: Implicit Namespace Packages :
Natywne wsparcie dla katalogów pakietów, które nie wymagają plików znaczników
__init__.py
i mogą automatycznie obejmować wiele segmentów ścieżek (inspirowane różnymi podejściami stron trzecich do przestrzeni nazw pakietów, jak opisano w PEP 420)
Oto test:
$ mkdir -p /tmp/test_init
$ touch /tmp/test_init/module.py /tmp/test_init/__init__.py
$ tree -at /tmp/test_init
/tmp/test_init
├── module.py
└── __init__.py
$ python3
>>> import sys
>>> sys.path.insert(0, '/tmp')
>>> from test_init import module
>>> import test_init.module
$ rm -f /tmp/test_init/__init__.py
$ tree -at /tmp/test_init
/tmp/test_init
└── module.py
$ python3
>>> import sys
>>> sys.path.insert(0, '/tmp')
>>> from test_init import module
>>> import test_init.module
References:
https://docs.python.org/3/whatsnew/3.3.html#pep-420-implicit-namespace-packages
https://www.python.org/dev/peps/pep-0420/
/ align = "left" / init__.py nie jest wymagane dla pakietów w Pythonie 3?
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-05-23 12:10:41
W Pythonie definicja pakietu jest bardzo prosta. Podobnie jak Java struktura hierarchiczna i struktura katalogów są takie same. Ale musisz mieć __init__.py
w opakowaniu. Wyjaśnię plik __init__.py
poniższym przykładem:
package_x/
|-- __init__.py
|-- subPackage_a/
|------ __init__.py
|------ module_m1.py
|-- subPackage_b/
|------ __init__.py
|------ module_n1.py
|------ module_n2.py
|------ module_n3.py
__init__.py
może być pusty, o ile istnieje. Oznacza to, że katalog powinien być traktowany jako pakiet. Oczywiście __init__.py
może również ustawić odpowiednią treść.
Jeśli dodamy funkcję w module_n1:
def function_X():
print "function_X in module_n1"
return
Po przebieg:
>>>from package_x.subPackage_b.module_n1 import function_X
>>>function_X()
function_X in module_n1
Następnie podążaliśmy za pakietem hierarchii i nazwaliśmy module_n1 funkcją. Możemy użyć __init__.py
w subPackage_b w następujący sposób:
__all__ = ['module_n2', 'module_n3']
Po uruchomieniu:
>>>from package_x.subPackage_b import *
>>>module_n1.function_X()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named module_n1
Stąd używanie * importowanie, pakiet modułów podlega zawartości __init__.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
2014-03-17 18:20:39
__init__.py
będzie traktował katalog, w którym się znajduje, jako moduł do ładowania.
Dla osób, które wolą czytać kod, umieszczam tutaj Two-Bit alchemist ' s komentarz.
$ find /tmp/mydir/
/tmp/mydir/
/tmp/mydir//spam
/tmp/mydir//spam/__init__.py
/tmp/mydir//spam/module.py
$ cd ~
$ python
>>> import sys
>>> sys.path.insert(0, '/tmp/mydir')
>>> from spam import module
>>> module.myfun(3)
9
>>> exit()
$
$ rm /tmp/mydir/spam/__init__.py*
$
$ python
>>> import sys
>>> sys.path.insert(0, '/tmp/mydir')
>>> from spam import module
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named spam
>>>
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-05-23 12:10:41
Co to jest __init__.py używany do?
Podstawowym zastosowaniem __init__.py
jest inicjalizacja pakietów Pythona. Najprostszym sposobem na zademonstrowanie tego jest przyjrzenie się strukturze standardowego modułu Pythona.
package/
__init__.py
file.py
file2.py
file3.py
subpackage/
__init__.py
submodule1.py
submodule2.py
Jak widać w powyższej strukturze włączenie pliku __init__.py
do katalogu wskazuje interpreterowi Pythona, że katalog powinien być traktowany jak pakiet Pythona
Co wchodzi __init__.py
?
__init__.py
może być pusty plik, ale jest on często używany do wykonania konfiguracji wymaganej dla pakietu(import rzeczy, załadowanie rzeczy do path, itd.).
Jedną z najczęstszych rzeczy do zrobienia w __init__.py
jest importowanie wybranych klas, funkcji itp.do poziomu pakietu, aby można było je wygodnie importować z pakietu.
W powyższym przykładzie możemy powiedzieć, że file.py ma akta klasowe. Więc bez czegokolwiek w naszej __init__.py
zaimportowałbyś z tą składnią:
from package.file import File
Można jednak zaimportować plik do swojego __init__.py
aby go udostępnić na poziomie pakietu:
# in your __init__.py
from file import File
# now import File from package
from package import File
Kolejną rzeczą do zrobienia jest na poziomie pakietu udostępnienie podpakietów / modułów ze zmienną __all__
. Gdy interpeter widzi zmienną __all__
zdefiniowaną w __init__.py
, importuje Moduły wymienione w zmiennej __all__
, gdy to zrobisz:
from package import *
__all__
jest to lista zawierająca nazwy modułów, które chcesz zaimportować za pomocą import*, więc patrząc na nasz powyższy przykład ponownie, jeśli chcemy zaimportować moduły podrzędne w zmienna __all__
w subpackage/__init__.py
będzie:
__all__ = ['submodule1', 'submodule2']
Ze zmienną __all__
wypełnioną w ten sposób, gdy wykonasz
from subpackage import *
Importowałby submodule1 i submodule2.
Jak widać __init__.py
może być bardzo przydatny oprócz swojej podstawowej funkcji wskazywania, że katalog jest modułem.
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
2018-03-03 04:40:14
Ułatwia importowanie innych plików Pythona. Po umieszczeniu tego pliku w katalogu (powiedzmy rzeczy)zawierającym inne pliki py, możesz zrobić coś takiego jak import rzeczy.inne.
root\
stuff\
other.py
morestuff\
another.py
Bez tego __init__.py
wewnątrz katalogu rzeczy, nie można importować other.py, ponieważ Python nie wie, gdzie znajduje się kod źródłowy rzeczy i nie jest w stanie rozpoznać go jako pakietu.
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
2013-06-08 10:45:40
Chociaż Python działa bez pliku __init__.py
, nadal powinieneś go dołączyć.
Określa, że pakiet powinien być traktowany jako moduł, więc dołącz go (nawet jeśli jest pusty).
Istnieje również przypadek, w którym możesz użyć pliku __init__.py
:
wyobraź sobie, że masz następującą strukturę plików:
main_methods
|- methods.py
I methods.py
zawierały to:
def foo():
return 'foo'
Aby użyć foo()
, potrzebujesz jednego z następujących elementów:
from main_methods.methods import foo # Call with foo()
from main_methods import methods # Call with methods.foo()
import main_methods.methods # Call with main_methods.methods.foo()
Maybe tam musisz (lub chcesz) przechowywać methods.py
wewnątrz main_methods
(na przykład runtimes/dependencies), ale chcesz tylko zaimportować main_methods
.
Jeśli zmieniłeś nazwę methods.py
na __init__.py
, możesz użyć foo()
po prostu importując main_methods
:
import main_methods
print(main_methods.foo()) # Prints 'foo'
To działa, ponieważ {[4] } jest traktowany jako część pakietu.
Niektóre pakiety Pythona faktycznie to robią. Przykładem jest JSON, gdzie uruchamianie import json
jest faktycznie importowaniem __init__.py
z json
pakietu ( zobacz struktura plików pakietu tutaj):
Kod źródłowy:
Lib/json/__init__.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
2018-05-18 07:48:38