Pertanyaan Untuk apa __init__.py?


apa yang __init__.py karena dalam direktori sumber Python?


1411
2018-01-15 20:09


asal


Jawaban:


Ini bagian dari paket. Berikut dokumentasinya.

Itu __init__.py file diperlukan untuk membuat Python memperlakukan direktori sebagai paket yang berisi; ini dilakukan untuk mencegah direktori dengan nama umum, seperti string, dari secara tidak sengaja menyembunyikan modul valid yang terjadi kemudian (lebih dalam) di jalur pencarian modul. Dalam kasus yang paling sederhana, __init__.py hanya bisa menjadi file kosong, tetapi juga dapat mengeksekusi kode inisialisasi untuk paket atau mengatur __all__ variabel, dijelaskan nanti.


975
2018-01-15 20:13



File bernama __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 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, jadi upaya untuk mengimpor modul akan gagal.

Itu __init__.py file biasanya kosong, tetapi dapat digunakan untuk mengekspor bagian yang dipilih dari paket di bawah nama yang lebih nyaman, tahan fungsi kenyamanan, dll. Diberikan contoh di atas, isi dari modul init dapat diakses sebagai

import spam

berdasarkan ini


597
2017-11-07 03:31



Selain memberi label direktori sebagai paket dan mendefinisikan Python __all__, __init__.py memungkinkan Anda menentukan variabel apa pun di tingkat paket. Melakukannya sering kali mudah jika sebuah paket mendefinisikan sesuatu yang akan sering diimpor, dengan cara yang mirip API. Pola ini mendorong kepatuhan pada filsafat "datar lebih baik dari pada nested".

Sebuah contoh

Berikut ini contoh dari salah satu proyek saya, di mana saya sering mengimpor sessionmaker bernama 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 Session di sini, saya dapat memulai sesi baru menggunakan sintaks di bawah ini. Kode ini akan dieksekusi sama dari dalam atau di luar direktori paket "database".

from database import Session
session = Session()

Tentu saja, ini adalah kenyamanan kecil - alternatifnya adalah mendefinisikan Session dalam file baru seperti "create_session.py" di paket database saya, dan mulai sesi baru menggunakan:

from database.create_session import Session
session = Session()

Bacaan lebih lanjut

Ada thread reddit yang cukup menarik yang mencakup penggunaan yang tepat __init__.py sini:

http://www.reddit.com/r/Python/comments/1bbbwk/whats_your_opinion_on_what_to_include_in_init_py/

Pendapat mayoritas tampaknya seperti itu __init__.py file harus sangat tipis untuk menghindari melanggar filosofi "eksplisit lebih baik daripada implisit".


366
2017-09-24 10:38



Ada 2 alasan utama untuk __init__.py

  1. Untuk kenyamanan: pengguna lain tidak perlu mengetahui lokasi persis fungsi Anda dalam hirarki 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
    

    maka yang lain dapat memanggil add () oleh

    from your_package import add
    

    tanpa mengetahui file1, seperti

    from your_package.file1 import add
    
  2. Jika Anda ingin sesuatu diinisialisasi; misalnya, penebangan (yang harus diletakkan di tingkat atas):

    import logging.config
    logging.config.dictConfig(Your_logging_config)
    

103
2018-04-08 08:29



Itu __init__.py file membuat Python memperlakukan direktori yang memuatnya sebagai modul.

Selain itu, ini adalah file pertama yang dimuat dalam modul, sehingga Anda dapat menggunakannya untuk mengeksekusi kode yang ingin Anda jalankan setiap kali modul dimuat, atau tentukan submodul yang akan diekspor.


87
2018-01-15 20:22



Sejak Python 3.3, __init__.py tidak lagi diperlukan untuk mendefinisikan direktori sebagai paket Python yang dapat diimpor.

Memeriksa PEP 420: Paket Namespace Implisit:

Dukungan asli untuk direktori paket yang tidak diperlukan __init__.py file penanda dan dapat secara otomatis menjangkau beberapa segmen jalur (terinspirasi oleh berbagai pendekatan pihak ketiga ke paket namespace, seperti yang dijelaskan di 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 dengan Python 3? 


45
2017-10-12 06:36



Dalam Python definisi paket sangat sederhana. Seperti Java, struktur hirarkis dan struktur direktori adalah sama. Tetapi Anda harus memilikinya __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. 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 menjalankan:

>>>from package_x.subPackage_b.module_n1 import function_X
>>>function_X()

function_X in module_n1 

Kemudian kami mengikuti paket hirarki dan memanggil modul_n1 fungsi. Kita bisa gunakan __init__.py di subPackage_b seperti ini:

__all__ = ['module_n2', 'module_n3']

Setelah menjalankan:

>>>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 dikenakan __init__.py konten.


44
2018-01-09 11:45



__init__.py akan memperlakukan direktori itu sebagai modul yang dapat dimuat.

Bagi orang yang lebih suka membaca kode, saya letakkan Dua-Bit Alchemist beri 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
>>> 

35
2018-01-03 17:41



Untuk apa __init__.py digunakan?

Penggunaan utama dari __init__.py adalah untuk menginisialisasi paket Python. Cara termudah untuk menunjukkan ini adalah dengan melihat struktur modul Python standar.

package/
    __init__.py
    file.py
    file2.py
    file3.py
    subpackage/
        __init__.py
        submodule1.py
        submodule2.py

Seperti yang Anda lihat dalam struktur di atas masuknya __init__.py file dalam direktori menunjukkan kepada interpreter Python bahwa direktori harus diperlakukan seperti paket Python

Apa yang masuk __init__.py?

__init__.py dapat berupa file kosong tetapi sering digunakan untuk melakukan pengaturan yang diperlukan untuk paket (mengimpor barang, memuat sesuatu ke jalur, dll).

Satu hal yang biasa dilakukan di Anda __init__.py adalah untuk mengimpor Kelas, fungsi, dll yang dipilih ke dalam level paket sehingga mereka dapat diimpor dari paket.

Dalam contoh di atas kita dapat mengatakan file.py itu memiliki File Kelas. Jadi tanpa apa pun di kami __init__.py Anda akan mengimpor dengan sintaks ini:

from package.file import File

Namun Anda dapat mengimpor file ke file Anda __init__.py untuk membuatnya tersedia di tingkat paket:

# in your __init__.py
from file import File

# now import File from package
from package import File

Hal lain yang harus dilakukan adalah pada level paket membuat sub-paket / modul tersedia dengan __all__ variabel. Ketika interpeter melihat suatu __all__ variabel didefinisikan dalam suatu __init__.py itu mengimpor modul yang terdaftar di __all__ variabel saat Anda melakukannya:

from package import *

__all__adalah daftar yang berisi nama-nama modul yang ingin Anda impor dengan impor * jadi perhatikan contoh di atas kami lagi jika kami ingin mengimpor submodul dalam sub-paket __all__ variabel dalam subpackage/__init__.py akan menjadi:

__all__ = ['submodule1', 'submodule2']

Dengan __all__ variabel diisi seperti itu, ketika Anda melakukan

from subpackage import *

itu akan mengimpor submodule1 dan submodule2.

Seperti yang Anda lihat __init__.py bisa sangat berguna selain fungsi utamanya untuk menunjukkan bahwa direktori adalah modul.

Referensi


26
2017-12-17 06:09



Ini memfasilitasi mengimpor file python lainnya. Ketika Anda menempatkan file ini di direktori (katakanlah hal-hal) yang berisi file py lainnya, maka Anda dapat melakukan sesuatu seperti barang impor.

root\
    stuff\
         other.py

    morestuff\
         another.py

Tanpa ini __init__.py di dalam hal direktori, Anda tidak dapat mengimpor other.py, karena Python tidak tahu di mana kode sumber untuk hal-hal itu dan tidak dapat mengenalinya sebagai paket.


25
2018-01-15 20:18



Meskipun Python berfungsi tanpa __init__.py file Anda harus tetap menyertakannya.

Ini menentukan paket harus diperlakukan sebagai modul, jadi karena itu masukkan (bahkan jika itu kosong).

Ada juga kasus di mana Anda benar-benar dapat menggunakan __init__.py mengajukan: 

Bayangkan Anda memiliki struktur file berikut:

main_methods 
    |- methods.py

Dan methods.py berisi ini:

def foo():
    return 'foo'

Menggunakan foo() Anda akan membutuhkan 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) menyimpannya methods.py dalam main_methods (runtimes / dependencies misalnya) tetapi Anda hanya ingin mengimpor main_methods.


Jika Anda mengubah nama methods.py untuk __init__.py maka Anda bisa menggunakannya foo() dengan hanya 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 benar-benar melakukan ini. Contohnya adalah dengan JSON, tempat berlari import json sebenarnya mengimpor __init__.py dari json paket (lihat struktur file paket di sini):

Kode sumber:  Lib/json/__init__.py


4
2018-05-12 15:41