CINXE.COM
PEP 257 - Соглашения для строк документации (docstrings) Python с нуля до бесконечности
<!DOCTYPE html> <html lang="ru"> <head> <meta charset="utf-8"> <link rel="stylesheet" href="/pyplanet_tmpl/fonts/style.css"> <link rel="stylesheet" href="/pyplanet_tmpl/css/new_style.css"> <title>PEP 257 - Соглашения для строк документации (docstrings) Python с нуля до бесконечности</title> <meta name="description" content='Этот PEP описывает семантику и соглашения, связанные со строками документации Python.'> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="apple-touch-icon" sizes="76x76" href="/apple-touch-icon.png"> <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"> <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"> <link rel="manifest" href="/site.webmanifest"> <link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5"> <meta name="msapplication-TileColor" content="#da532c"> <meta name="theme-color" content="#f5f5f5"> <script type="text/javascript" > (function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)}; m[i].l=1*new Date(); for (var j = 0; j < document.scripts.length; j++) {if (document.scripts[j].src === r) { return; }} k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)}) (window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym"); ym(97429815, "init", { clickmap:true, trackLinks:true, accurateTrackBounce:true, webvisor:true }); </script> <noscript><div><img src="https://mc.yandex.ru/watch/97429815" style="position:absolute; left:-9999px;" alt="" /></div></noscript> <script>window.yaContextCb=window.yaContextCb||[]</script> <script src="https://yandex.ru/ads/system/context.js" async></script> </head> <body> <header> <div class="logo"><a href="/"><img src="/pyplanet_tmpl/img/python-3.png"></a></div> <div class="logo-letters"><a href="/">Pyplanet — Python с нуля до бесконечности</a></div> </header> <div class="category-menu"> <a href="/category/osnovy.html">Основы</a> <a href="/category/enhanced.html">Продвинутый</a> <a href="/category/guidebook.html">Справочник</a> <a href="/pages/tutorials.html">Руководства</a> <a href="/pages/books.html">Книги</a> <a href="/pages/courses.html">Курсы</a> </div> <div class="main-content"> <div class="content"> <article class="post"> <h1>PEP 257 - Соглашения для строк документации (docstrings)</h1> <div class="text-block"> <div id="yandex_rtb_R-A-9079088-3" style="max-height: 10%"></div> <div id="content_top" style="display: none"> <a target="_blank" href="https://zallj.com/g/qqb62fps0r99b979a60661cec322b98fba714163/?erid=5jtCeReNwxHpfQTDve31wmc"> <img src="/pyplanet_tmpl/img/content_top.png"> </a> </div> <script> window.yaContextCb.push(() => { Ya.Context.AdvManager.render({ "blockId": "R-A-9079088-3", "renderTo": "yandex_rtb_R-A-9079088-3" }); }) setTimeout( function () { if (document.getElementById("yandex_rtb_R-A-9079088-3").clientHeight === 0) { document.getElementById("content_top").style.display = 'block'; } }, 500); </script> <div class="section" id="section-1"> <h2>Аннотация</h2> <p>Этот PEP описывает семантику и соглашения, связанные со строками документации Python.</p> </div> <div class="section" id="section-2"> <h2>Обоснование</h2> <p>Целью данного PEP является стандартизация структуры строк документации: что они должны содержать и что они должны объяснять (не затрагивая синтаксис разметки внутри строк документации). PEP содержит соглашения, а не законы или синтаксис.</p> <blockquote> <p>“Универсальное соглашение обеспечивает удобство сопровождения, ясность, последовательность, а также закладывает основу для хороших привычек программирования. Что оно <strong>не</strong> делает, так это настаивает на том, чтобы вы ему следовали против своей воли. Это Python!”</p> <p>- Тим Питерс, comp.lang.python, 2001-06-16</p> </blockquote> <p>Если вы нарушите эти соглашения, самое худшее, что вас ждет — несколько неодобрительных взглядов. Однако некоторые программы (например, системы обработки строк документации, такие как <em>Docutils</em>, упомянутые в PEP 256 и PEP 258) используют эти соглашения. Поэтому их соблюдение приведет к лучшим результатам.</p> </div> <div class="section" id="section-3"> <h2>Спецификация</h2> <div class="section" id="section-4"> <h3>Что такое строки документации?</h3> <p>Строки документации — это строковые литералы, расположенные первыми внутри тела модуля, функции, класса или метода. Такая строка документации становится значением специального атрибута <tt class="docutils literal">__doc__</tt> соответствующего объекта.</p> <p>Все модули должны, как правило, иметь строки документации, и все функции и классы, экспортируемые модулем также должны иметь строки документации. Публичные методы (в том числе <tt class="docutils literal">__init__</tt>) также должны иметь строки документации. Пакет модулей может быть документирован в <tt class="docutils literal">__init__.py</tt> в директории пакета.</p> <p>Строковые литералы, используемые в других местах кода Python, также могут выполнять функцию документации. Однако такие строки не обрабатываются компилятором байткода Python и не доступны как атрибуты <tt class="docutils literal">__doc__</tt>. Программные инструменты могут извлекать два дополнительных типа документации:</p> <ol class="arabic simple"> <li>Строковые литералы, встречающиеся сразу после простого присваивания на верхнем уровне модуля, класса или метода <tt class="docutils literal">__init__</tt>, называются "строкой документации атрибута".</li> <li>Строковые литералы, встречающиеся сразу после другой строки документации, называются "дополнительной строкой документации".</li> </ol> <p>Подробнее о них можно узнать в PEP 258, “Docutils Design Specification”.</p> <p>Для согласованности, всегда используйте <tt class="docutils literal"><span class="pre">"""три</span> двойные <span class="pre">кавычки"""</span></tt> для строк документации. Используйте <tt class="docutils literal"><span class="pre">r"""сырую</span> строку три двойные <span class="pre">кавычки"""</span></tt>, если вы будете использовать обратную косую черту в строке документации.</p> <p>Существует две формы строк документации: однострочная и многострочная.</p> </div> <div class="section" id="section-5"> <h3>Однострочные строки документации</h3> <p>Однострочники предназначены для действительно очевидных случаев. Они должны умещаться на одной строке. Например:</p> <div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">kos_root</span><span class="p">():</span> <span class="w"> </span><span class="sd">"""Return the pathname of the KOS root directory."""</span> <span class="k">global</span> <span class="n">_kos_root</span> <span class="k">if</span> <span class="n">_kos_root</span><span class="p">:</span> <span class="k">return</span> <span class="n">_kos_root</span> </pre></div> <ul> <li><p class="first">Используйте тройные кавычки, даже если документация умещается на одной строке. Это облегчает дальнейшее расширение документации.</p> </li> <li><p class="first">Закрывающие кавычки располагаются на той же строке, что и содержимое.</p> </li> <li><p class="first">Нет пустых строк перед или после строки документации, сразу идет код.</p> </li> <li><p class="first">Строка документации - это фраза, заканчивающаяся точкой. Она поясняет действие функции или метода в императивном тоне ("Сделай это", "Верни то"), а не как описание; например, не пишите "Возвращает имя пути ...".</p> <div class="note docutils container"> <p>Значение фразы "императивный тон" в английском языке в оригинале поясняется на примере словосочетаний "Return pathname" и "Returns pathname". PEP-257 предписывает придерживаться первого стиля, потому что он более строгий.</p> </div> </li> <li><p class="first">Однострочная строка документации не должна быть "подписью" параметров функции / метода (которые могут быть получены с помощью интроспекции). Не делайте:</p> <div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">function</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span> <span class="w"> </span><span class="sd">"""function(a, b) -> list"""</span> </pre></div> <p>Этот тип строк документации подходит только для C функций (таких, как встроенные модули), где интроспекция не представляется возможной. Тем не менее, возвращаемое значение не может быть определено путем интроспекции. Предпочтительный вариант для такой строки документации будет что-то вроде:</p> <div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">function</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span> <span class="w"> </span><span class="sd">"""Do X and return a list."""</span> </pre></div> <p>(Конечно, "Do X" следует заменить полезным описанием!)</p> </li> </ul> </div> <div class="section" id="section-6"> <h3>Многострочные строки документации</h3> <p>Многострочные строки документации состоят из сводной строки (summary line), имеющей такую же структуру, как и однострочная строка документации. Она должна быть отделена от последующего текста пустой строкой, а затем следует более подробное описание.</p> <p>Первая строка может быть использована автоматическими средствами индексации, поэтому важно, чтобы она занимала ровно одну строку и была отделена от остальной документации пустой строкой. Первая строка может быть на той же строке, где и открывающие кавычки, или на следующей строке. Вся документация должна иметь такой же отступ, как кавычки на первой строке (см. пример ниже).</p> <p>Вставляйте пустую строку до и после всех строк документации (однострочных или многострочных), которые документируют класс - вообще говоря, методы класса разделены друг от друга одной пустой строкой, а строка документации должна быть смещена от первого метода пустой строкой; для симметрии, поставьте пустую строку между заголовком класса и строкой документации.</p> <p>Строки документации скрипта (самостоятельной программы) должны быть доступны в качестве "сообщения по использованию", напечатанной, когда программа вызывается с некорректными или отсутствующими аргументами (или, возможно, с опцией "-h", для помощи). Такая строка документации должна документировать функции программы и синтаксис командной строки, переменные окружения и файлы. Сообщение по использованию может быть довольно сложным (несколько экранов) и должно быть достаточным для нового пользователя для использования программы должным образом, а также полный справочник со всеми вариантами и аргументами для искушенного пользователя.</p> <p>Строки документации <a class="reference external" href="https://pyplanet.ru/article/import.html">модуля</a> должны, как правило, перечислять классы, исключения, функции (и любые другие объекты), которые экспортируются модулем, с краткими пояснениями (в одну строчку) каждого из них. (Эти строки, как правило, дают меньше деталей, чем первая строка документации к объекту). Строки документации пакета модулей (т.е. строка документации в <tt class="docutils literal">__init__.py</tt>) также должны включать модули и подпакеты.</p> <p>Строки документации <a class="reference external" href="https://pyplanet.ru/article/def-return.html">функции</a> или метода должны обобщить его поведение и документировать свои аргументы, возвращаемые значения, побочные эффекты, исключения, дополнительные аргументы, именованные аргументы, и ограничения на вызов функции.</p> <p>Строки документации <a class="reference external" href="https://pyplanet.ru/article/classes.html">класса</a> обобщают его поведение и перечисляют открытые методы и переменные экземпляра. Если класс предназначен для подклассов, и имеет дополнительный интерфейс для подклассов, этот интерфейс должен быть указан отдельно (в строке документации). Конструктор класса должен быть задокументирован в документации метода <tt class="docutils literal">__init__</tt>. Отдельные методы должны иметь свои строки документации.</p> <p>Если класс - подкласс другого класса, и его поведение в основном унаследовано от этого класса, строки документации должны отмечать это и обобщить различия. Используйте глагол "override", чтобы указать, что метод подкласса заменяет метод суперкласса и не вызывает его; используйте глагол "extend", чтобы указать, что метод подкласса вызывает метод суперкласса (в дополнение к собственному поведению).</p> <p>Не используйте соглашение Emacs, согласно которому аргументы функций или методов указываются в верхнем регистре в тексте. Python чувствителен к регистру, а имена аргументов могут быть использованы в качестве именованных аргументов, поэтому в строке документации должны быть указаны правильные имена аргументов. Лучше всего перечислять каждый аргумент в отдельной строке. Например:</p> <div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">complex</span><span class="p">(</span><span class="n">real</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span> <span class="n">imag</span><span class="o">=</span><span class="mf">0.0</span><span class="p">):</span> <span class="w"> </span><span class="sd">"""Form a complex number.</span> <span class="sd"> Keyword arguments:</span> <span class="sd"> real -- the real part (default 0.0)</span> <span class="sd"> imag -- the imaginary part (default 0.0)</span> <span class="sd"> """</span> <span class="k">if</span> <span class="n">imag</span> <span class="o">==</span> <span class="mf">0.0</span> <span class="ow">and</span> <span class="n">real</span> <span class="o">==</span> <span class="mf">0.0</span><span class="p">:</span> <span class="k">return</span> <span class="n">complex_zero</span> <span class="o">...</span> </pre></div> <p>Если только вся строка документа не помещается в одной строке, поместите закрывающие кавычки в отдельной строке.</p> </div> <div class="section" id="section-7"> <h3>Обработка отступов строк документации</h3> <p>Инструменты обработки строк документаци должны удалять одинаковое количество отступов, равное минимальному отступу всех не пустых строк, начиная со второй.</p> <p>Любые отступы в первой строке документации несущественны и будут удалены. Относительный отступ более поздних строк в строке документа сохраняется. Пустые строки должны быть удалены из начала и конца строки документа.</p> <p>Поскольку код гораздо точнее слов, здесь приведена реализация алгоритма:</p> <div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">trim</span><span class="p">(</span><span class="n">docstring</span><span class="p">):</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">docstring</span><span class="p">:</span> <span class="k">return</span> <span class="s1">''</span> <span class="c1"># Convert tabs to spaces (following the normal Python rules)</span> <span class="c1"># and split into a list of lines:</span> <span class="n">lines</span> <span class="o">=</span> <span class="n">docstring</span><span class="o">.</span><span class="n">expandtabs</span><span class="p">()</span><span class="o">.</span><span class="n">splitlines</span><span class="p">()</span> <span class="c1"># Determine minimum indentation (first line doesn't count):</span> <span class="n">indent</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">maxsize</span> <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">lines</span><span class="p">[</span><span class="mi">1</span><span class="p">:]:</span> <span class="n">stripped</span> <span class="o">=</span> <span class="n">line</span><span class="o">.</span><span class="n">lstrip</span><span class="p">()</span> <span class="k">if</span> <span class="n">stripped</span><span class="p">:</span> <span class="n">indent</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="n">indent</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">line</span><span class="p">)</span> <span class="o">-</span> <span class="nb">len</span><span class="p">(</span><span class="n">stripped</span><span class="p">))</span> <span class="c1"># Remove indentation (first line is special):</span> <span class="n">trimmed</span> <span class="o">=</span> <span class="p">[</span><span class="n">lines</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">strip</span><span class="p">()]</span> <span class="k">if</span> <span class="n">indent</span> <span class="o"><</span> <span class="n">sys</span><span class="o">.</span><span class="n">maxsize</span><span class="p">:</span> <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">lines</span><span class="p">[</span><span class="mi">1</span><span class="p">:]:</span> <span class="n">trimmed</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">line</span><span class="p">[</span><span class="n">indent</span><span class="p">:]</span><span class="o">.</span><span class="n">rstrip</span><span class="p">())</span> <span class="c1"># Strip off trailing and leading blank lines:</span> <span class="k">while</span> <span class="n">trimmed</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">trimmed</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]:</span> <span class="n">trimmed</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span> <span class="k">while</span> <span class="n">trimmed</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">trimmed</span><span class="p">[</span><span class="mi">0</span><span class="p">]:</span> <span class="n">trimmed</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="c1"># Return a single string:</span> <span class="k">return</span> <span class="s1">'</span><span class="se">\n</span><span class="s1">'</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">trimmed</span><span class="p">)</span> </pre></div> <p>Документация в следующем примере содержит два символа новой строки и поэтому имеет длину равную трём. Первая и последняя строки пусты:</p> <div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">foo</span><span class="p">():</span> <span class="w"> </span><span class="sd">"""</span> <span class="sd"> This is the second line of the docstring.</span> <span class="sd"> """</span> </pre></div> <p>Проиллюстрируем:</p> <div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="nb">print</span> <span class="nb">repr</span><span class="p">(</span><span class="n">foo</span><span class="o">.</span><span class="vm">__doc__</span><span class="p">)</span> <span class="go">'\n This is the second line of the docstring.\n '</span> <span class="gp">>>> </span><span class="n">foo</span><span class="o">.</span><span class="vm">__doc__</span><span class="o">.</span><span class="n">splitlines</span><span class="p">()</span> <span class="go">['', ' This is the second line of the docstring.', ' ']</span> <span class="gp">>>> </span><span class="n">trim</span><span class="p">(</span><span class="n">foo</span><span class="o">.</span><span class="vm">__doc__</span><span class="p">)</span> <span class="go">'This is the second line of the docstring.'</span> </pre></div> <p>Однако после обработки следующие строки документации будут эквивалентны:</p> <div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">foo</span><span class="p">():</span> <span class="w"> </span><span class="sd">"""A multi-line</span> <span class="sd"> docstring.</span> <span class="sd"> """</span> </pre></div> <div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">bar</span><span class="p">():</span> <span class="w"> </span><span class="sd">"""</span> <span class="sd"> A multi-line</span> <span class="sd"> docstring.</span> <span class="sd"> """</span> </pre></div> <div class="note docutils container"> <p>Вы можете также использовать модуль <tt class="docutils literal">inspect</tt> и его метод <tt class="docutils literal">cleandoc()</tt> для обработки строк документации.</p> <div class="highlight"><pre><span></span><span class="n">inspect</span><span class="o">.</span><span class="n">cleandoc</span><span class="p">(</span><span class="n">foo</span><span class="o">.</span><span class="vm">__doc__</span><span class="p">)</span> </pre></div> </div> </div> </div> <div id="yandex_rtb_R-A-9079088-1" style="max-height: 25%"></div> <div id="content_bottom" style="display: none"> <a target="_blank" href="https://zallj.com/g/qqb62fps0r99b979a60661cec322b98fba714163/?erid=5jtCeReNwxHpfQTDve31wmc"> <img src="/pyplanet_tmpl/img/content_bottom.png"> </a> </div> <script> window.yaContextCb.push(() => { Ya.Context.AdvManager.render({ "blockId": "R-A-9079088-1", "renderTo": "yandex_rtb_R-A-9079088-1" }); }) setTimeout( function () { if (document.getElementById("yandex_rtb_R-A-9079088-3").clientHeight === 0) { document.getElementById("content_bottom").style.display = 'block'; } }, 1000); </script> <nav class="nav-cycle"> <div> </div> <div> <a href="/category/enhanced/pep.html">В категорию "PEP - Python Enhancement Proposal"</a> </div> <div> </div> </nav> </div> </article> </div> <div class="sidebar"> <div class="sticky"> <div class="button-group"> <a target="_blank" href="https://t.me/pyplanet"><button class="telegram-button">✈ Telegram</button></a> <a target="_blank" href="https://www.tinkoff.ru/cf/6xIycbvJQF9"><button class="tinkoff-button">❤️ Поддержать</button></a> <a target="_blank" href="https://forms.gle/Trx4h8zZwKyBpsyY6"><button class="ask-button">❓ Задать вопрос</button></a> </div> <div class="latest-articles"> <h3>Популярные статьи</h3> <div class="article"> <h4><a href="https://pyplanet.ru/article/range-object.html">Объект range</a></h4> <p>Изучение объекта range в Python. Создание последовательностей чисел, использование в циклах и примеры применения.</p> </div> <div class="article"> <h4><a href="https://pyplanet.ru/article/pep-0257.html">PEP 257 - соглашения для строк документации (docstrings)</a></h4> <p>Целью данного PEP является стандартизация структуры строк документации: что они должны содержать и что должны объяснять.</p> </div> <div class="article"> <h4><a href="https://pyplanet.ru/pages/courses-free.html">Бесплатные курсы Python</a></h4> <p>Обзор бесплатных курсов, обучающих видео по языку программирования Python</p> </div> </div> </div> </div> </div> <footer> <p>© 2025 <a href="https://pyplanet.ru/">pyplanet - Python с нуля до бесконечности</a></p> </footer> </body> </html>