Přidání kódu __init__.py

hlasů
77

Já jsem při pohledu na to, jak tento model systém Django funguje a všiml jsem si něco, čemu nerozumím.

Vím, že jste vytvořit prázdný __init__.pysoubor, který stanoví, že je aktuální adresář balíček. A že můžete nastavit nějakou proměnnou __init__.py, takže import * funguje správně.

Ale Django přidává spoustu z ... Importovat ... závěrku a vymezuje spoustu tříd __init__.py. Proč? Není to jen dělat věci vypadají chaotický? Je nějaký důvod, který vyžaduje tento kód __init__.py?

Položena 23/09/2008 v 05:41
zdroj uživatelem
V jiných jazycích...                            


3 odpovědí

hlasů
68

Všechny dovoz __init__.pyjsou k dispozici při importu balíček (adresář), který jej obsahuje.

Příklad:

./dir/__init__.py:

import something

./test.py:

import dir
# can now use dir.something

EDIT: zapomněl zmínit, kód v __init__.pybězích poprvé importovat jakýkoliv modul z tohoto adresáře. Takže je to obvykle dobré místo pro jakékoliv inicializační kód balíček úrovni.

EDIT2: dgrant poukázal na možné záměny v mém příkladu. V __init__.py import somethingumí importovat jakýkoliv modul, není nutné z obalu. Například, můžeme jej nahradit import datetime, a pak v naší nejvyšší úrovni test.pyobou těchto úryvků bude fungovat:

import dir
print dir.datetime.datetime.now()

a

import dir.some_module_in_dir
print dir.datetime.datetime.now()

Sečteno podtrženo: všechny názvy přiřazené oblasti __init__.py, ať už se jedná dováženy modulů, funkcí nebo tříd, jsou automaticky k dispozici v příbalovém názvů kdykoli importovat balíček nebo modul v balení.

Odpovězeno 23/09/2008 v 05:47
zdroj uživatelem

hlasů
33

Je to jen osobní preference ve skutečnosti, a má co do činění s uspořádáním svých python moduly.

Řekněme, že máte modul s názvem erikutils. Existují dva způsoby, že to může být modul, ať už máte soubor s názvem erikutils.py na tvé sys.path, nebo máte adresář s názvem erikutils na vaší sys.paths prázdným __init__.pysouborem uvnitř. Pak řekněme, že máte spoustu modulů zvaných fileutils, procutils, parseutilsa chcete osob, které budou podmoduly pod erikutils. Tak se stane, že .py soubory nazývané fileutils.py , procutils.py a parseutils.py :

erikutils
  __init__.py
  fileutils.py
  procutils.py
  parseutils.py

Možná, že máte několik funkcí, které prostě nepatří do fileutils, procutilsnebo parseutilsmodulů. A řekněme, že nemáte pocit, že vytvoří nový modul s názvem miscutils. A byste chtěli mít možnost volání funkce jako tak:

erikutils.foo()
erikutils.bar()

spíše než dělat

erikutils.miscutils.foo()
erikutils.miscutils.bar()

Tak proto, že erikutilsmodul je adresář, ne soubor, musíme definovat, že je funkce uvnitř __init__.pysouboru.

V Django, nejlepší příklad mě napadá je django.db.models.fields. Všechny třídy poli django * jsou definovány v __init__.pysouboru v / db / Modely / polí Django adresáře. Myslím, že to udělal, protože nechtěl, aby nacpat všechno do hypotetického Django / db / Modely / fields.py modelu, takže se rozdělit ji do několika dílčích modulů ( related.py , files.py , například) a že přilepená z * definice polí v oblasti samotném modul (tedy __init__.py).

Odpovězeno 23/09/2008 v 07:12
zdroj uživatelem

hlasů
26

Použití __init__.pysouboru umožňuje, aby vnitřní struktura balíček neviditelný z vnějšku. V případě, že vnitřní změny struktury (například z důvodu rozdělit jeden modul tuku na dvě části) máte jen upravit __init__.pysoubor, ale nikoli kód, který závisí na obalu. Můžete také součástí balení neviditelné, například v případě, že nejsou připraveny pro všeobecné použití.

Všimněte si, že můžete použít delpříkaz, tak typický __init__.pymůže vypadat například takto:

from somemodule import some_function1, some_function2, SomeObject

del somemodule

Nyní, pokud jste se rozhodli rozdělit somemodulenový __init__.pymůže být:

from somemodule1 import some_function1, some_function2
from somemodule2 import SomeObject

del somemodule1
del somemodule2

Zvenčí balíček stále vypadá přesně jako předtím.

Odpovězeno 24/09/2008 v 12:02
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more