Apa __init__.py
untuk di Python direktori source?
Ini digunakan untuk menjadi bagian dari paket (tua, pra-3.3 "paket reguler", tidak baru 3.3+ "namespace paket").
Python mendefinisikan dua jenis paket, regular paket dan namespace paket. Reguler paket tradisional paket-paket seperti mereka ada di Python 3.2 dan sebelumnya. Paket reguler biasanya diimplementasikan sebagai sebuah direktori yang berisi
__init__.py
file. Ketika sebuah paket reguler adalah impor, ini__init__.py
file secara implisit dieksekusi, dan benda-benda yang mendefinisikan terikat untuk nama-nama dalam paket namespace. The__init__.py
file dapat berisi sama kode Python yang lain modul dapat berisi, dan Python akan menambahkan beberapa atribut tambahan untuk modul ketika itu diimpor.
Tapi hanya klik link, berisi contoh, informasi, dan penjelasan dari namespace paket, jenis paket tanpa __init__.py
.
File yang bernama __init__.py
digunakan untuk menandai direktori pada disk sebagai Python paket direktori.
Jika anda memiliki file
mydir/spam/__init__.py
mydir/spam/module.py
dan dirsaya
di jalan anda, anda dapat mengimpor kode dalam 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 tersebut, sehingga upaya untuk mengimpor modul akan gagal.
The __init__.py
file yang biasanya kosong, tetapi dapat digunakan untuk ekspor bagian-bagian yang dipilih dari paket di bawah lebih nyaman nama, tahan fungsi kenyamanan, dll.
Diberikan contoh di atas, isi init modul dapat diakses sebagai
import spam
berdasarkan ini
Selain pelabelan sebuah direktori sebagai paket Python dan mendefinisikan __semua__
, __init__.py
memungkinkan anda untuk mendefinisikan setiap variabel pada paket tingkat. Demikian ini sering nyaman jika sebuah paket mendefinisikan sesuatu yang akan diimpor sering, di API-seperti fashion. Pola ini mempromosikan kepatuhan terhadap Pythonic "datar lebih baik dari yang bersarang" filsafat.
Berikut ini adalah contoh dari salah satu proyek saya, di mana saya sering mengimpor sessionmaker
disebut Sesi
untuk berinteraksi dengan database saya. Aku menulis "database" paket 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)
Sejak saya mendefinisikan Sesi
di sini, saya dapat memulai sesi baru menggunakan sintaks di bawah ini. Kode ini akan dieksekusi dari dalam atau luar dari "database" paket direktori.
from database import Session
session = Session()
Tentu saja, ini adalah kenyamanan kecil-alternatif yang akan menentukan Sesi
di file baru seperti "create_session.py" di database saya paket, dan memulai sesi baru dengan menggunakan:
from database.create_session import Session
session = Session()
Ada yang cukup menarik reddit thread meliputi penggunaan yang tepat dari __init__.py
di 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 "eksplisit lebih baik dari implisit" filsafat.
Ada 2 alasan utama untuk __init__.py
your_package/ __init__.py file1.py file2.py ... fileN.py
``
dari file1 impor dari file2 impor ... dari fileN impor * ``
``
def add(): lulus ``
maka orang lain dapat memanggil add() dengan
dari your_package impor add
tanpa mengetahui file1, seperti
dari your_package.file1 impor add
impor logging.config logging.config.dictConfig(Your_logging_config)
The __init__.py
membuat file Python mengobati direktori yang berisi sebagai modul.
Selain itu, ini adalah file pertama yang akan dimuat dalam sebuah modul, sehingga anda dapat menggunakannya untuk mengeksekusi kode yang ingin anda jalankan setiap kali modul ini dimuat, atau menentukan submodul untuk diekspor.
Sejak Python 3.3, __init__.py
tidak lagi diperlukan untuk menentukan direktori sebagai diimpor paket Python.
Check PEP 420: Implisit Namespace Paket:
dukungan Asli untuk paket direktori yang tidak memerlukan
__init__.py
penanda file dan secara otomatis dapat span beberapa segmen jalan (terinspirasi oleh berbagai pihak ketiga pendekatan untuk namespace paket, seperti yang dijelaskan dalam PEP 420)
Berikut ini's tes:
$ 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/ https://stackoverflow.com/questions/37139786/is-init-py-not-required-for-packages-in-python-3
Di Python definisi dari paket ini sangat sederhana. Seperti Jawa, struktur hirarki dan struktur direktori yang sama. Tapi anda harus memiliki __init__.py
dalam 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. Hal ini menunjukkan bahwa direktori harus dianggap sebagai sebuah paket. Tentu saja, __init__.py
juga dapat mengatur konten yang sesuai.
Jika kita menambahkan fungsi di module_n1:
def function_X():
print "function_X in module_n1"
return
Setelah berjalan:
>>>from package_x.subPackage_b.module_n1 import function_X
>>>function_X()
function_X in module_n1
Kemudian kami mengikuti hirarki paket dan disebut module_n1 fungsi. Kita dapat menggunakan __init__.py
di subPackage_b seperti ini:
__all__ = ['module_n2', 'module_n3']
Setelah berjalan:
>>>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 * mengimpor, paket modul tunduk __init__.py
konten.
Meskipun Python bekerja tanpa __init__.py
file anda masih harus memiliki satu.
Ini menentukan paket harus diperlakukan sebagai sebuah modul, sehingga karena itu termasuk itu (bahkan jika itu adalah kosong).
Ada juga kasus di mana anda mungkin benar-benar menggunakan __init__.py
file:
Bayangkan anda memiliki file berikut struktur:
main_methods
|- methods.py
Dan methods.py
ini terkandung:
def foo():
return 'foo'
Untuk menggunakan foo()
anda akan membutuhkan salah satu dari 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 ada yang anda butuhkan (atau ingin) untuk menjaga methods.py
dalam main_methods
(runtimes/dependensi misalnya) tapi anda hanya ingin mengimpor main_methods
.
Jika anda mengubah nama methods.py
untuk __init__.py
maka anda bisa menggunakan foo()
dengan hanya mengimpor main_methods
:
import main_methods
print(main_methods.foo()) # Prints 'foo'
Ini bekerja karena __init__.py
diperlakukan sebagai bagian dari paket.
Beberapa paket Python yang benar-benar melakukan ini. Contohnya adalah dengan JSON, di mana berjalan import json
adalah benar-benar mengimpor __init__.py
dari json
paket (lihat paket struktur file disini):
Source code:
Lib/json/__init__.py
__init__.py
akan memperlakukan direktori ini adalah sebagai loadable modul.
Bagi orang-orang yang lebih memilih membaca kode, saya menempatkan Dua-Bit Alchemist's komentar 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
>>>
Memfasilitasi mengimpor lain python file. Ketika anda menempatkan file ini dalam direktori (mengatakan hal-hal)yang mengandung lain py file, maka anda dapat melakukan sesuatu seperti impor barang-barang.lain.
root\
stuff\
other.py
morestuff\
another.py
Tanpa ini __init__.py
di dalam direktori hal-hal, anda tidak't impor other.py karena Python doesn't tahu di mana kode sumber untuk barang-barang dan tidak mampu mengenalinya sebagai sebuah paket.
Sebuah __init__.py
membuat file impor mudah. Ketika sebuah __init__.py
ini hadir dalam satu paket, fungsi a()
dapat diimpor dari file b.py
seperti:
b mengimpor
Tanpa itu, namun, anda dapat't impor langsung. Anda harus mengubah sistem jalan:
``
import sys
sys.jalan.insert(0, 'path/to/b.py')
b mengimpor ``