Vraag Waarvoor is __init__.py?


Wat is __init__.py voor in een Python-bronmap?


1411
2018-01-15 20:09


oorsprong


antwoorden:


Het maakt deel uit van een pakket. Hier is de documentatie.

De __init__.py bestanden zijn nodig om Python de mappen te laten behandelen als pakketjes; Dit wordt gedaan om te voorkomen dat mappen met een algemene naam, zoals string, van het per ongeluk verbergen van geldige modules die later (dieper) op het zoekpad van de module voorkomen. In het eenvoudigste geval __init__.py kan gewoon een leeg bestand zijn, maar het kan ook initialisatiecode voor het pakket uitvoeren of de __all__ variabele, later beschreven.


975
2018-01-15 20:13



Bestanden genoemd __init__.py worden gebruikt om mappen op schijf te markeren als Python-pakketmappen. Als je de bestanden hebt

mydir/spam/__init__.py
mydir/spam/module.py

en mydir is op uw pad, u kunt de code importeren module.py als

import spam.module

of

from spam import module

Als u de __init__.py bestand, zoekt Python niet langer naar submodules in die map, dus pogingen om de module te importeren zullen mislukken.

De __init__.py bestand is meestal leeg, maar kan worden gebruikt om geselecteerde delen van het pakket te exporteren onder een meer handige naam, handige functies vast te houden, enz. Gezien het bovenstaande voorbeeld is de inhoud van de init-module toegankelijk als

import spam

gebaseerd op deze


597
2017-11-07 03:31



Naast het labelen van een directory als een Python-pakket en het definiëren __all__, __init__.py kunt u elke variabele op het niveau van het pakket definiëren. Dit is vaak handig als een pakket iets definieert dat vaak zal worden geïmporteerd, op een API-achtige manier. Dit patroon bevordert de naleving van de Pythonic "flat is better than nested" -filosofie.

Een voorbeeld

Hier is een voorbeeld van een van mijn projecten, waarin ik vaak een sessionmaker riep Session om te communiceren met mijn database. Ik schreef een "database" -pakket met een paar modules:

database/
    __init__.py
    schema.py
    insertions.py
    queries.py

Mijn __init__.py bevat de volgende code:

import os

from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine

engine = create_engine(os.environ['DATABASE_URL'])
Session = sessionmaker(bind=engine)

Omdat ik definieer Session hier kan ik een nieuwe sessie starten met behulp van de onderstaande syntaxis. Deze code zou hetzelfde zijn, uitgevoerd van binnen of buiten de "database" -map van het pakket.

from database import Session
session = Session()

Natuurlijk is dit een klein gemak - het alternatief zou zijn om te definiëren Session in een nieuw bestand zoals "create_session.py" in mijn databasepakket en start nieuwe sessies met behulp van:

from database.create_session import Session
session = Session()

Verder lezen

Er is een redelijk interessante reddit-thread voor geschikt gebruik van __init__.py hier:

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

De mening van de meerderheid lijkt dat te zijn __init__.py bestanden moeten erg dun zijn om te voorkomen dat de "expliciete is beter dan impliciete" filosofie wordt geschonden.


366
2017-09-24 10:38



Er zijn 2 hoofdredenen voor __init__.py

  1. Voor het gemak: de andere gebruikers hoeven de exacte locatie van uw functies in uw pakkethiërarchie niet te weten.

    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
    

    dan kunnen anderen add () by aanroepen

    from your_package import add
    

    zonder bestand1 te kennen, zoals

    from your_package.file1 import add
    
  2. Als u wilt dat er iets wordt geïnitialiseerd; logboekregistratie (die op het hoogste niveau moet worden geplaatst):

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

103
2018-04-08 08:29



De __init__.py bestand zorgt ervoor dat Python mappen behandelt die deze als modules bevatten.

Bovendien is dit het eerste bestand dat in een module moet worden geladen, zodat u het kunt gebruiken om code uit te voeren die u wilt uitvoeren elke keer dat een module wordt geladen, of om de submodules te specificeren die moeten worden geëxporteerd.


87
2018-01-15 20:22



Sinds Python 3.3, __init__.py is niet langer vereist om mappen te definiëren als importeerbare Python-pakketten.

Controleren PEP 420: Impliciete naamruimtepakketten:

Native ondersteuning voor pakketmappen die niet nodig zijn __init__.py markeerbestanden en kan automatisch meerdere padsegmenten overspannen (geïnspireerd door verschillende benaderingen van derden voor naamruimtepakketten, zoals beschreven in PEP 420)

Dit is de 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

referenties:
https://docs.python.org/3/whatsnew/3.3.html#pep-420-implicit-namespace-packages
https://www.python.org/dev/peps/pep-0420/
Is __init__.py niet vereist voor pakketten in Python 3? 


45
2017-10-12 06:36



In Python is de definitie van pakket heel eenvoudig. Net als Java zijn de hiërarchische structuur en de directorystructuur hetzelfde. Maar je moet hebben __init__.py in een pakket. Ik zal het uitleggen __init__.py bestand met het onderstaande voorbeeld:

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 kan leeg zijn, zolang het bestaat. Het geeft aan dat de map moet worden beschouwd als een pakket. Natuurlijk, __init__.py kan ook de juiste inhoud instellen.

Als we een functie toevoegen in module_n1:

def function_X():
    print "function_X in module_n1"
    return

Na het rennen:

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

function_X in module_n1 

Daarna volgden we het hiërarchiepakket en noemden module_n1 de functie. We kunnen gebruiken __init__.py in subPackage_b zoals dit:

__all__ = ['module_n2', 'module_n3']

Na het rennen:

>>>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

Vandaar dat met behulp van * importeren, module-pakket is onderworpen aan __init__.py inhoud.


44
2018-01-09 11:45



__init__.py behandelt de map waarin deze zich bevindt als een laadbare module.

Voor mensen die liever lezen, ik zet Tweekleurige alchemisten reageer hier.

$ 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



Waarvoor wordt __init__.py gebruikt?

Het primaire gebruik van __init__.py is om Python-pakketten te initialiseren. De eenvoudigste manier om dit aan te tonen, is door een kijkje te nemen naar de structuur van een standaard Python-module.

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

Zoals je kunt zien in de bovenstaande structuur is de opname van de __init__.py bestand in een map geeft aan de Python-interpreter aan dat de map moet worden behandeld als een Python-pakket

Wat gaat erin __init__.py?

__init__.py kan een leeg bestand zijn, maar wordt vaak gebruikt om de instellingen uit te voeren die nodig zijn voor het pakket (dingen importeren, dingen laden in het pad, enz.).

Een veelvoorkomend ding om te doen in uw __init__.py is om geselecteerde klassen, functies, enz. in het pakketniveau te importeren, zodat ze op gepaste wijze uit het pakket kunnen worden geïmporteerd.

In het bovenstaande voorbeeld kunnen we stellen dat file.py het klassenbestand heeft. Dus zonder iets in onze __init__.py je zou met deze syntaxis importeren:

from package.file import File

U kunt echter het bestand importeren in uw __init__.py om het beschikbaar te maken op pakketniveau:

# in your __init__.py
from file import File

# now import File from package
from package import File

Een ander ding om te doen is om op pakketniveau subpakketten / modules beschikbaar te maken met de __all__ variabel. Wanneer de interpeter een ziet __all__ variabele gedefinieerd in een __init__.py het importeert de modules vermeld in de __all__ variabele als je dat doet:

from package import *

__all__is een lijst met de namen van modules die u wilt importeren met import * dus als u ons bovenstaande voorbeeld opnieuw bekijkt, willen we de submodules importeren in subpakket de __all__ variabele in subpackage/__init__.py zou zijn:

__all__ = ['submodule1', 'submodule2']

Met de __all__ variabele bevolkt als dat, wanneer je speelt

from subpackage import *

het zou submodule1 en submodule2 importeren.

Zoals je kan zien __init__.py kan erg nuttig zijn naast zijn primaire functie om aan te geven dat een map een module is.

Referentie


26
2017-12-17 06:09



Het vergemakkelijkt het importeren van andere python-bestanden. Wanneer je dit bestand in een directory (zeg dingen) met andere py-bestanden hebt geplaatst, kun je iets als import dingen doen.

root\
    stuff\
         other.py

    morestuff\
         another.py

Zonder dit __init__.py Binnen de directory-dingen kon je geen andere.py importeren, omdat Python niet weet waar de broncode voor spullen is en niet in staat is om het als pakket te herkennen.


25
2018-01-15 20:18



Hoewel Python werkt zonder een __init__.py bestand moet je er nog steeds een toevoegen.

Het specificeert dat een pakket moet worden behandeld als een module, dus neem het dus op (zelfs als het leeg is).

Er is ook een geval waarin u daadwerkelijk een __init__.py het dossier: 

Stel je voor dat je de volgende bestandsstructuur had:

main_methods 
    |- methods.py

En methods.py bevatte dit:

def foo():
    return 'foo'

Gebruiken foo() je hebt een van de volgende dingen nodig:

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()

Misschien moet je daar (of wilt) behouden methods.py binnen main_methods (runtimes / afhankelijkheden bijvoorbeeld) maar u wilt alleen importeren main_methods.


Als u de naam van hebt gewijzigd methods.py naar __init__.py dan zou je kunnen gebruiken foo() door gewoon te importeren main_methods:

import main_methods
print(main_methods.foo()) # Prints 'foo'

Dit werkt omdat __init__.py wordt behandeld als onderdeel van het pakket.


Sommige Python-pakketten doen dit. Een voorbeeld is met JSON, waar rennen import json is eigenlijk aan het importeren __init__.py van de json pakket (zie hier de bestandsstructuur van het pakket):

Broncode:  Lib/json/__init__.py


4
2018-05-12 15:41