βοΈ __init__.py
__init__.py is a special Python file used inside a package.
It can be used to initialize the package and control what gets imported from it.
π¦ Example
my_package/
β
βββ __init__.py
βββ calculator.py
βββ greeting.pyHere, my_package is the package and __init__.py belongs to it.
πΉ Using __init__.py
Suppose calculator.py contains:
def add(a, b):
return a + bWe can import it through the package:
from my_package.calculator import add
print(add(10, 5))π‘ Important
In modern Python, a folder can work as a package without __init__.py (namespace packages).
However, __init__.py is still commonly used because it can:
Initialize package-level code
Expose selected functions/classes
Control package imports
β Remember
π¦ Package
β
βββ __init__.py β Package initialization
βββ calculator.py
βββ greeting.py__init__.py β Special file associated with a Python package.
<div class="infographic-pyinit">
<style>
.infographic-pyinit {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--mono-font: 'IBM Plex Mono', 'SFMono-Regular', Menlo, monospace;
--display-font: 'Fraunces', Georgia, serif;
--body-font: 'Inter', system-ui, sans-serif;
box-sizing: border-box;
max-width: 760px;
margin: 0 auto;
font-family: var(--body-font);
color: var(--ink);
background: var(--paper);
}
.infographic-pyinit[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
}
.infographic-pyinit *, .infographic-pyinit *::before, .infographic-pyinit *::after { box-sizing: border-box; }
.infographic-pyinit .in-wrap { padding: 0 clamp(1rem, 4vw, 2rem) 1.5rem; }
.infographic-pyinit h1 {
font-family: var(--display-font); font-weight: 600;
font-size: clamp(1.5rem, 5vw, 2.05rem); text-align: center; margin: 1.5rem 0 0.25rem; letter-spacing: -0.01em;
}
.infographic-pyinit .in-sub { text-align: center; color: var(--ink-soft); font-size: 0.86rem; margin: 0 0 1.4rem; }
.infographic-pyinit .layout { display: grid; grid-template-columns: 190px 1fr; gap: 1.3rem; margin-bottom: 1.2rem; }
@media (max-width: 560px) { .infographic-pyinit .layout { grid-template-columns: 1fr; } }
.infographic-pyinit .tree {
font-family: var(--mono-font); font-size: 0.82rem; background: var(--paper-alt);
border: 1px solid var(--line); border-radius: 8px; padding: 0.8rem 0.9rem;
}
.infographic-pyinit .tree-row { padding: 0.15rem 0; white-space: nowrap; color: var(--ink-soft); }
.infographic-pyinit .tree-row.init { color: var(--accent); font-weight: 700; }
.infographic-pyinit .tree-row.pkg { color: var(--ink); font-weight: 700; }
.infographic-pyinit .preset-row { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-bottom: 0.7rem; }
.infographic-pyinit .preset-btn {
font: inherit; font-family: var(--mono-font); font-size: 0.76rem; font-weight: 700;
background: var(--paper-alt); border: 1.5px solid var(--line); color: var(--ink-soft);
padding: 0.35rem 0.6rem; cursor: pointer; border-radius: 6px;
}
.infographic-pyinit .preset-btn.is-selected { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }
.infographic-pyinit .init-code {
font-family: var(--mono-font); font-size: 0.8rem; white-space: pre;
background: var(--paper-alt); border: 1px solid var(--line); border-radius: 8px;
padding: 0.7rem 0.85rem; color: var(--ink); min-height: 3.4em;
}
.infographic-pyinit .init-code .cm { color: var(--ink-soft); }
.infographic-pyinit .try-label {
text-align: center; font-size: 0.72rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em;
color: var(--ink-soft); margin: 1.2rem 0 0.5rem;
}
.infographic-pyinit .try-row { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.4rem; margin-bottom: 1rem; }
.infographic-pyinit .try-btn {
font: inherit; font-family: var(--mono-font); font-size: 0.78rem; font-weight: 700;
background: var(--paper-alt); border: 1.5px solid var(--line); color: var(--ink);
padding: 0.4rem 0.7rem; cursor: pointer; border-radius: 6px;
}
.infographic-pyinit .device {
--ed-bg: #1e1e1e; --ed-bar: #2d2d2d; --ed-text: #d4d4d4; --ed-soft: #8a8a8a; --ed-ok: #6fdc8c; --ed-err: #ff6b6b;
background: var(--ed-bg); border: 1px solid var(--line); border-radius: 8px; overflow: hidden;
}
.infographic-pyinit .device-bar {
display: flex; align-items: center; gap: 0.4rem;
background: var(--ed-bar); padding: 0.5rem 0.7rem; border-bottom: 1px solid #3a3a3a;
font-size: 0.72rem; color: var(--ed-soft); font-weight: 600;
}
.infographic-pyinit .device-bar .dot { width: 9px; height: 9px; border-radius: 50%; background: #5a5a5a; }
.infographic-pyinit .device-bar .dot:nth-child(1) { background: #ff5f56; }
.infographic-pyinit .device-body { padding: 0.75rem 0.9rem; font-family: var(--mono-font); font-size: 0.8rem; color: var(--ed-text); min-height: 50px; max-height: 170px; overflow-y: auto; }
.infographic-pyinit .log-line { display: flex; gap: 0.5rem; line-height: 1.7; opacity: 0; animation: in-fadein 0.25s ease forwards; flex-wrap: wrap; }
@keyframes in-fadein { from { opacity: 0; transform: translateY(3px); } to { opacity: 1; transform: translateY(0); } }
.infographic-pyinit .log-line .p { color: var(--ed-ok); font-weight: 700; }
.infographic-pyinit .log-line.err .out { color: var(--ed-err); font-weight: 700; }
.infographic-pyinit .log-line.ok .out { color: var(--ed-ok); font-weight: 700; }
.infographic-pyinit .log-line .out { color: #fff; }
.infographic-pyinit .log-empty { color: var(--ed-soft); }
.infographic-pyinit .in-caption { text-align: center; font-size: 0.85rem; color: var(--ink-soft); margin-top: 0.9rem; }
@media (prefers-reduced-motion: reduce) {
.infographic-pyinit *, .infographic-pyinit *::before, .infographic-pyinit *::after {
animation-duration: 0.001ms !important; transition-duration: 0.001ms !important;
}
}
</style>
<div class="in-wrap">
<h1>__init__.py</h1>
<p class="in-sub">The file that runs when a package gets imported β and decides what the package exposes.</p>
<div class="layout">
<div class="tree">
<div class="tree-row pkg">mypackage/</div>
<div class="tree-row init"> __init__.py</div>
<div class="tree-row"> shapes.py</div>
<div class="tree-row" style="padding-left:1.2rem; opacity:.7;">class Circle</div>
<div class="tree-row" style="padding-left:1.2rem; opacity:.7;">class Square</div>
</div>
<div>
<div class="preset-row" id="presetRow"></div>
<div class="init-code" id="initCode"></div>
</div>
</div>
<div class="try-label">Try an import</div>
<div class="try-row" id="tryRow"></div>
<div class="device">
<div class="device-bar"><span class="dot"></span><span class="dot"></span><span class="dot"></span> Terminal</div>
<div class="device-body" id="initLog"><div class="log-empty">Pick an __init__.py version, then try an import.</div></div>
</div>
<p class="in-caption" id="initCaption">An empty __init__.py still makes mypackage a package β it just re-exports nothing.</p>
</div>
<script>
(function () {
var root = document.currentScript.closest('.infographic-pyinit')
|| document.querySelector('.infographic-pyinit');
var bodyAttr = document.body.getAttribute('data-darkmode');
var dark;
if (bodyAttr === 'true') { dark = true; }
else if (bodyAttr === 'false') { dark = false; }
else {
var match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) root.setAttribute('data-theme', 'dark');
var presets = [
{
key: 'empty', label: 'empty', code: '<span class="cm"># (nothing here)</span>',
exports: [], hasAll: false, allList: [],
caption: 'An empty __init__.py still makes mypackage a package β it just re-exports nothing.'
},
{
key: 'reexport', label: 'from .shapes import ...', code: 'from .shapes import Circle, Square',
exports: ['Circle', 'Square'], hasAll: false, allList: [],
caption: 'Re-exporting in __init__.py lets people skip the submodule name entirely.'
},
{
key: 'all', label: '+ __all__', code: 'from .shapes import Circle, Square\n__all__ = [\'Circle\']',
exports: ['Circle', 'Square'], hasAll: true, allList: ['Circle'],
caption: '__all__ only limits from mypackage import * β Square is still reachable by name directly.'
}
];
var currentPreset = 'empty';
var presetRow = root.querySelector('#presetRow');
var initCode = root.querySelector('#initCode');
var tryRow = root.querySelector('#tryRow');
var initLog = root.querySelector('#initLog');
var initCaption = root.querySelector('#initCaption');
var firstLog = true;
presets.forEach(function (p) {
var btn = document.createElement('button');
btn.className = 'preset-btn' + (p.key === currentPreset ? ' is-selected' : '');
btn.textContent = p.label;
btn.addEventListener('click', function () {
root.querySelectorAll('#presetRow .preset-btn').forEach(function (b) { b.classList.remove('is-selected'); });
btn.classList.add('is-selected');
currentPreset = p.key;
renderPreset();
});
presetRow.appendChild(btn);
});
function renderPreset() {
var p = presets.filter(function (x) { return x.key === currentPreset; })[0];
initCode.innerHTML = p.code;
initCaption.textContent = p.caption;
}
var tries = [
{ key: 'direct', label: 'from mypackage import Circle' },
{ key: 'submodule', label: 'from mypackage.shapes import Circle' },
{ key: 'star', label: 'from mypackage import *' }
];
tries.forEach(function (t) {
var btn = document.createElement('button');
btn.className = 'try-btn';
btn.textContent = t.label;
btn.addEventListener('click', function () { runTry(t.key, t.label); });
tryRow.appendChild(btn);
});
function logLine(text, cls) {
if (firstLog) { initLog.innerHTML = ''; firstLog = false; }
var line = document.createElement('div');
line.className = 'log-line' + (cls ? ' ' + cls : '');
line.innerHTML = '<span class="p">>>></span><span class="out">' + text + '</span>';
initLog.appendChild(line);
initLog.scrollTop = initLog.scrollHeight;
}
function runTry(key, label) {
var p = presets.filter(function (x) { return x.key === currentPreset; })[0];
if (key === 'submodule') {
logLine(label, null);
logLine('β works β submodule imports never depend on __init__.py content', 'ok');
return;
}
if (key === 'direct') {
logLine(label, null);
if (p.exports.indexOf('Circle') !== -1) {
logLine('β works β Circle was re-exported in __init__.py', 'ok');
} else {
logLine('β ImportError: cannot import name \'Circle\' from \'mypackage\'', 'err');
}
return;
}
if (key === 'star') {
logLine(label, null);
if (p.exports.length === 0) {
logLine('β imports nothing β __init__.py never brought Circle or Square in', 'err');
} else if (p.hasAll) {
logLine('β imports only: ' + p.allList.join(', ') + ' (__all__ controls this)', 'ok');
} else {
logLine('β imports everything re-exported: ' + p.exports.join(', '), 'ok');
}
}
}
renderPreset();
})();
</script>
</div>