Respuestas:
Solía ser una parte requerida de un paquete ( antiguo "paquete regular" anterior a 3.3 , no más nuevo 3.3+ "paquete de espacio de nombres" ).
Python define dos tipos de paquetes, paquetes regulares y paquetes de espacio de nombres. Los paquetes regulares son paquetes tradicionales tal como existían en Python 3.2 y versiones anteriores. Un paquete normal generalmente se implementa como un directorio que contiene un
__init__.py
archivo. Cuando se importa un paquete normal, este__init__.py
archivo se ejecuta implícitamente y los objetos que define están vinculados a nombres en el espacio de nombres del paquete. El__init__.py
archivo puede contener el mismo código de Python que cualquier otro módulo puede contener, y Python agregará algunos atributos adicionales al módulo cuando se importe.
Pero solo haga clic en el enlace, contiene un ejemplo, más información y una explicación de los paquetes de espacios de nombres, el tipo de paquetes sin ellos __init__.py
.
sys.path.insert(0, '/path/to/datetime')
, reemplazando esa ruta con la ruta al directorio que acaba de crear. Ahora intenta algo como from datetime import datetime;datetime.now()
. Debería obtener un AttributeError (porque ahora está importando su archivo en blanco). Si repitiera estos pasos sin crear el archivo de inicio en blanco, esto no sucedería. Eso es lo que se pretende prevenir.
from datetime import datetime
sin error. ¡Eso es bueno desde la versión 2.3!
builtins
enumera funciones y clases integradas, no módulos integrados (cf. docs.python.org/3/tutorial/modules.html#the-dir-function ). Si desea enumerar los módulos integrados , haga import sys; print(sys.builtin_module_names)
(cf. docs.python.org/3/library/sys.html#sys.builtin_module_names ).
Los archivos nombrados __init__.py
se usan para marcar directorios en el disco como directorios de paquetes Python. Si tienes los archivos
mydir/spam/__init__.py
mydir/spam/module.py
y mydir
está en su camino, puede importar el código module.py
como
import spam.module
o
from spam import module
Si elimina el __init__.py
archivo, Python ya no buscará submódulos dentro de ese directorio, por lo que los intentos de importar el módulo fallarán.
El __init__.py
archivo generalmente está vacío, pero se puede usar para exportar partes seleccionadas del paquete con un nombre más conveniente, mantener funciones convenientes, etc. Dado el ejemplo anterior, se puede acceder al contenido del módulo init como
import spam
basado en esto
__init__.py
se requería en Python 2.X y todavía se requiere en Python 2.7.12 (lo probé) pero ya no se requiere (supuestamente) en Python 3.3 en adelante, y no se requiere en Python 3.4.3 (I probado) Consulte stackoverflow.com/questions/37139786 para más detalles.
__init__.py
.
setup.py
y usa find_packages()
, es necesario tenerlo __init__.py
en cada directorio. Ver stackoverflow.com/a/56277323/7127824
Además de etiquetar un directorio como un paquete de Python y definirlo __all__
, le __init__.py
permite definir cualquier variable a nivel de paquete. Hacerlo suele ser conveniente si un paquete define algo que se importará con frecuencia, de forma similar a la API. Este patrón promueve la adhesión a la filosofía pitónica "plano es mejor que anidado".
Aquí hay un ejemplo de uno de mis proyectos, en el que frecuentemente importo un sessionmaker
llamado Session
para interactuar con mi base de datos. Escribí un paquete de "base de datos" con algunos módulos:
database/
__init__.py
schema.py
insertions.py
queries.py
Mi __init__.py
contiene el siguiente código:
import os
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
engine = create_engine(os.environ['DATABASE_URL'])
Session = sessionmaker(bind=engine)
Como lo defino Session
aquí, puedo comenzar una nueva sesión usando la sintaxis a continuación. Este código sería el mismo ejecutado desde dentro o fuera del directorio del paquete "base de datos".
from database import Session
session = Session()
Por supuesto, esto es una pequeña conveniencia: la alternativa sería definir Session
en un nuevo archivo como "create_session.py" en mi paquete de base de datos, y comenzar nuevas sesiones usando:
from database.create_session import Session
session = Session()
Hay un hilo de reddit bastante interesante que cubre los usos apropiados de __init__.py
aquí:
http://www.reddit.com/r/Python/comments/1bbbwk/whats_your_opinion_on_what_to_include_in_init_py/
La opinión mayoritaria parece ser que los __init__.py
archivos deben ser muy delgados para evitar violar la filosofía "explícito es mejor que implícito".
engine
, sessionmaker
, create_engine
, Y os
todos pueden también ser importados de database
ahora ... parece que usted ha hecho un lío de ese espacio de nombres.
__all__ = [...]
para limitar lo que se importa con import *
. Pero aparte de eso, sí, te queda un espacio de nombres de alto nivel desordenado.
Hay 2 razones principales para __init__.py
Por conveniencia: los otros usuarios no necesitarán conocer la ubicación exacta de sus funciones en la jerarquía de su paquete.
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
entonces otros pueden llamar a add () por
from your_package import add
sin saber file1, como
from your_package.file1 import add
Si quieres que algo se inicialice; por ejemplo, el registro (que debe colocarse en el nivel superior):
import logging.config
logging.config.dictConfig(Your_logging_config)
__init__.py
puede ser útil a veces, pero no siempre.
El __init__.py
archivo hace que Python trate los directorios que lo contienen como módulos.
Además, este es el primer archivo que se carga en un módulo, por lo que puede usarlo para ejecutar el código que desea ejecutar cada vez que se carga un módulo, o especificar los submódulos que se exportarán.
Desde Python 3.3, __init__.py
ya no es necesario definir directorios como paquetes Python importables.
Consulte PEP 420: Paquetes de espacio de nombres implícitos :
Soporte nativo para directorios de paquetes que no requieren
__init__.py
archivos de marcadores y que pueden abarcar automáticamente múltiples segmentos de ruta (inspirados en varios enfoques de terceros para paquetes de espacios de nombres, como se describe en PEP 420 )
Aquí está la prueba:
$ 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
referencias:
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 no se requiere para paquetes en Python 3?
En Python la definición de paquete es muy simple. Al igual que Java, la estructura jerárquica y la estructura de directorios son las mismas. Pero tienes que tenerlo __init__.py
en un paquete. Explicaré el __init__.py
archivo con el siguiente ejemplo:
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
puede estar vacío, siempre que exista. Indica que el directorio debe considerarse como un paquete. Por supuesto,__init__.py
también puede establecer el contenido apropiado.
Si agregamos una función en module_n1:
def function_X():
print "function_X in module_n1"
return
Despues de correr:
>>>from package_x.subPackage_b.module_n1 import function_X
>>>function_X()
function_X in module_n1
Luego seguimos el paquete de jerarquía y llamamos a module_n1 la función. Podemos usar __init__.py
en subPackage_b así:
__all__ = ['module_n2', 'module_n3']
Despues de correr:
>>>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
Por lo tanto, usando * importing, el paquete del módulo está sujeto a __init__.py
contenido.
from package_x.subPackage_b.module_n1 import function_X
Aunque Python funciona sin un __init__.py
archivo, aún debe incluir uno.
Especifica que un paquete debe tratarse como un módulo, por lo tanto, inclúyalo (incluso si está vacío).
También hay un caso en el que realmente puedes usar un __init__.py
archivo:
Imagine que tiene la siguiente estructura de archivos:
main_methods
|- methods.py
Y methods.py
contenía esto:
def foo():
return 'foo'
Para usarlo foo()
necesitaría uno de los siguientes:
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()
Tal vez allí necesite (o desee) mantenerse methods.py
dentro main_methods
(tiempos de ejecución / dependencias, por ejemplo), pero solo desea importar main_methods
.
Si cambiaste el nombre de methods.py
a __init__.py
, podrías usarlo foo()
simplemente importando main_methods
:
import main_methods
print(main_methods.foo()) # Prints 'foo'
Esto funciona porque __init__.py
se trata como parte del paquete.
Algunos paquetes de Python realmente hacen esto. Un ejemplo es con JSON , donde ejecutar import json
es importar __init__.py
desde el json
paquete ( vea la estructura del archivo del paquete aquí ):
Código fuente:
Lib/json/__init__.py
__init__.py
tratará el directorio en el que se encuentra como un módulo cargable.
Para las personas que prefieren leer el código, pongo el comentario de Two-Bit Alchemist aquí.
$ 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
>>>
Facilita la importación de otros archivos de Python. Cuando colocaste este archivo en un directorio (digamos cosas) que contiene otros archivos py, entonces puedes hacer algo como importar cosas.otras.
root\
stuff\
other.py
morestuff\
another.py
Sin esto __init__.py
dentro del directorio, no podría importar other.py, porque Python no sabe dónde está el código fuente de las cosas y no puede reconocerlo como un paquete.
Un __init__.py
archivo facilita las importaciones. Cuando un __init__.py
está presente dentro de un paquete, la función a()
se puede importar desde un archivo de esta b.py
manera:
from b import a
Sin él, sin embargo, no puede importar directamente. Tienes que modificar la ruta del sistema:
import sys
sys.path.insert(0, 'path/to/b.py')
from b import a