Jawaban:
Ini digunakan untuk menjadi bagian yang diperlukan dari sebuah paket ( lama, pra-3.3 "paket reguler" , bukan 3.3 "paket namespace" yang lebih baru ).
Python mendefinisikan dua jenis paket, paket reguler dan paket namespace. Paket reguler adalah paket tradisional seperti yang ada di Python 3.2 dan sebelumnya. Paket reguler biasanya diimplementasikan sebagai direktori yang berisi
__init__.py
file. Ketika paket reguler diimpor,__init__.py
file ini secara implisit dieksekusi, dan objek yang didefinisikannya terikat dengan nama-nama dalam namespace paket. The__init__.py
File dapat berisi kode Python yang sama bahwa setiap modul lainnya dapat berisi, dan Python akan menambahkan beberapa atribut tambahan untuk modul ketika diimpor.
Tapi cukup klik tautannya, itu berisi contoh, informasi lebih lanjut, dan penjelasan tentang paket namespace, jenis paket tanpa itu __init__.py
.
sys.path.insert(0, '/path/to/datetime')
, ganti path itu dengan path ke direktori apa pun yang baru saja Anda buat. Sekarang coba sesuatu seperti from datetime import datetime;datetime.now()
. Anda harus mendapatkan AttributeError (karena mengimpor file kosong Anda sekarang). Jika Anda mengulangi langkah-langkah ini tanpa membuat file init kosong, ini tidak akan terjadi. Itulah yang dimaksudkan untuk dicegah.
from datetime import datetime
tanpa kesalahan. Itu bagus sepanjang perjalanan kembali ke versi 2.3!
builtins
daftar fungsi dan kelas built-in, bukan modul built-in (lih. Docs.python.org/3/tutorial/modules.html#the-dir-function ). Jika Anda ingin daftar modul bawaan , lakukan import sys; print(sys.builtin_module_names)
(lih. Docs.python.org/3/library/sys.html#sys.builtin_module_names ).
File yang diberi nama __init__.py
digunakan untuk menandai direktori pada disk sebagai direktori paket Python. Jika Anda memiliki file
mydir/spam/__init__.py
mydir/spam/module.py
dan mydir
ada di jalur Anda, Anda dapat mengimpor kode module.py
sebagai
import spam.module
atau
from spam import module
Jika Anda menghapus __init__.py
file, Python tidak akan lagi mencari submodul di dalam direktori itu, sehingga upaya untuk mengimpor modul akan gagal.
The __init__.py
file biasanya kosong, tetapi dapat digunakan untuk mengekspor bagian yang dipilih dari paket dengan nama yang lebih nyaman, fungsi kenyamanan ditahan, dll Mengingat contoh di atas, isi modul init dapat diakses sebagai
import spam
berdasarkan ini
__init__.py
diperlukan di bawah Python 2.X dan masih diperlukan di bawah Python 2.7.12 (saya mengujinya) tetapi tidak lagi diperlukan dari (diduga) Python 3.3 dan seterusnya, dan tidak diperlukan di bawah Python 3.4.3 (I mengujinya). Lihat stackoverflow.com/questions/37139786 untuk lebih jelasnya.
__init__.py
.
setup.py
dan menggunakannya find_packages()
perlu ada __init__.py
di setiap direktori. Lihat stackoverflow.com/a/56277323/7127824
Selain memberi label pada direktori sebagai paket Python dan mendefinisikan __all__
, __init__.py
memungkinkan Anda untuk mendefinisikan variabel apa pun di tingkat paket. Melakukannya sering kali nyaman jika suatu paket mendefinisikan sesuatu yang akan sering diimpor, dengan cara seperti API. Pola ini mempromosikan kepatuhan pada filosofi "flat lebih baik daripada bersarang" dari Pythonic.
Berikut adalah contoh dari salah satu proyek saya, di mana saya sering mengimpor sessionmaker
disebut Session
untuk berinteraksi dengan database saya. Saya menulis paket "database" dengan beberapa modul:
database/
__init__.py
schema.py
insertions.py
queries.py
Saya __init__.py
berisi kode berikut:
import os
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
engine = create_engine(os.environ['DATABASE_URL'])
Session = sessionmaker(bind=engine)
Karena saya mendefinisikan di Session
sini, saya dapat memulai sesi baru menggunakan sintaksis di bawah ini. Kode ini akan sama dieksekusi dari dalam atau di luar direktori paket "database".
from database import Session
session = Session()
Tentu saja, ini adalah kenyamanan kecil - alternatifnya adalah dengan mendefinisikan Session
dalam file baru seperti "create_session.py" dalam paket database saya, dan mulai sesi baru menggunakan:
from database.create_session import Session
session = Session()
Ada thread reddit yang cukup menarik yang mencakup penggunaan yang sesuai di __init__.py
sini:
http://www.reddit.com/r/Python/comments/1bbbwk/whats_your_opinion_on_what_to_include_in_init_py/
Pendapat mayoritas tampaknya bahwa __init__.py
file harus sangat tipis untuk menghindari melanggar filosofi "eksplisit lebih baik daripada implisit".
engine
, sessionmaker
, create_engine
, Dan os
semua bisa juga diimpor dari database
sekarang ... sepertinya Anda telah membuat berantakan namespace itu.
__all__ = [...]
untuk membatasi apa yang diimpor dengan import *
. Tapi selain dari itu, ya, Anda memiliki namespace tingkat atas yang berantakan.
Ada 2 alasan utama __init__.py
Untuk kenyamanan: pengguna lain tidak perlu mengetahui lokasi pasti fungsi Anda di hierarki paket Anda.
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
kemudian orang lain dapat memanggil add () oleh
from your_package import add
tanpa mengetahui file1, suka
from your_package.file1 import add
Jika Anda ingin sesuatu diinisialisasi; misalnya, pencatatan (yang harus diletakkan di tingkat atas):
import logging.config
logging.config.dictConfig(Your_logging_config)
__init__.py
terkadang bermanfaat, tetapi tidak setiap saat.
The __init__.py
File membuat Python memperlakukan direktori yang berisi sebagai modul.
Selanjutnya, ini adalah file pertama yang dimuat dalam modul, sehingga Anda dapat menggunakannya untuk mengeksekusi kode yang ingin Anda jalankan setiap kali modul dimuat, atau menentukan submodul yang akan diekspor.
Sejak Python 3.3, __init__.py
tidak lagi diperlukan untuk mendefinisikan direktori sebagai paket Python yang dapat diimpor.
Periksa PEP 420: Paket Namespace Tersirat :
Dukungan asli untuk direktori paket yang tidak memerlukan
__init__.py
file penanda dan dapat secara otomatis menjangkau banyak segmen jalur (terinspirasi oleh berbagai pendekatan pihak ketiga untuk paket namespace, seperti dijelaskan dalam PEP 420 )
Inilah tesnya:
$ 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
referensi:
https://docs.python.org/3/whatsnew/3.3.html#pep-420-implicit-namespace-packages
https://www.python.org/dev/peps/pep-0420/
Apakah __init__. py tidak diperlukan untuk paket di Python 3?
Dalam Python definisi paket sangat sederhana. Seperti Java, struktur hierarkis dan struktur direktori adalah sama. Tetapi Anda harus memiliki __init__.py
satu paket. Saya akan menjelaskan __init__.py
file dengan contoh di bawah ini:
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
bisa kosong, asalkan ada. Ini menunjukkan bahwa direktori harus dianggap sebagai paket. Tentu saja, __init__.py
bisa juga mengatur konten yang sesuai.
Jika kita menambahkan fungsi di module_n1:
def function_X():
print "function_X in module_n1"
return
Setelah berlari:
>>>from package_x.subPackage_b.module_n1 import function_X
>>>function_X()
function_X in module_n1
Kemudian kami mengikuti paket hierarki dan memanggil module_n1 fungsinya. Kita dapat menggunakan __init__.py
di subPackage_b seperti ini:
__all__ = ['module_n2', 'module_n3']
Setelah berlari:
>>>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
Oleh karena itu menggunakan * impor, paket modul tergantung pada __init__.py
konten.
from package_x.subPackage_b.module_n1 import function_X
Meskipun Python bekerja tanpa __init__.py
file, Anda tetap harus memasukkannya.
Ini menentukan paket harus diperlakukan sebagai modul, jadi karena itu sertakan (bahkan jika itu kosong).
Ada juga kasus di mana Anda sebenarnya dapat menggunakan __init__.py
file:
Bayangkan Anda memiliki struktur file berikut:
main_methods
|- methods.py
Dan methods.py
berisi ini:
def foo():
return 'foo'
Untuk menggunakan foo()
Anda perlu salah satu dari yang berikut:
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()
Mungkin di sana Anda perlu (atau ingin) untuk tetap methods.py
di dalam main_methods
(runtimes / dependensi misalnya) tetapi Anda hanya ingin mengimpor main_methods
.
Jika Anda mengubah nama methods.py
untuk __init__.py
maka Anda dapat menggunakan foo()
hanya dengan mengimpor main_methods
:
import main_methods
print(main_methods.foo()) # Prints 'foo'
Ini berfungsi karena __init__.py
diperlakukan sebagai bagian dari paket.
Beberapa paket Python sebenarnya melakukan ini. Contohnya adalah dengan JSON , di mana menjalankan import json
sebenarnya mengimpor __init__.py
dari json
paket ( lihat struktur file paket di sini ):
Kode sumber:
Lib/json/__init__.py
__init__.py
akan memperlakukan direktori itu sebagai modul yang dapat dimuat.
Untuk orang-orang yang lebih suka membaca kode, saya menaruh komentar Two-Bit Alchemist di sini.
$ 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
>>>
Ini memfasilitasi mengimpor file python lainnya. Ketika Anda menempatkan file ini di direktori (katakan hal-hal) yang berisi file py lainnya, maka Anda dapat melakukan sesuatu seperti mengimpor barang.other.
root\
stuff\
other.py
morestuff\
another.py
Tanpa ini __init__.py
di dalam hal-hal direktori, Anda tidak dapat mengimpor other.py, karena Python tidak tahu di mana kode sumber untuk barang-barang itu dan tidak dapat mengenalinya sebagai paket.
Sebuah __init__.py
file yang membuat impor mudah. Ketika sebuah __init__.py
hadir dalam suatu paket, fungsi a()
dapat diimpor dari file b.py
seperti:
from b import a
Tanpa itu, Anda tidak dapat mengimpor secara langsung. Anda harus mengubah jalur sistem:
import sys
sys.path.insert(0, 'path/to/b.py')
from b import a