Документация Python неофициальный перевод

programming.md

1540 строк · 125.0 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/3.4/faq/programming.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# [ЧЗВ по программированию](https://python-all.ru/3.4/faq/programming.html#id1)89Содержание1011- [Вопросы по программированию](https://python-all.ru/3.4/faq/programming.html#programming-faq)1213  - [Общие вопросы](https://python-all.ru/3.4/faq/programming.html#general-questions)1415    - [Существует ли отладчик на уровне исходного кода с точками останова, пошаговым выполнением и т. д.?](https://python-all.ru/3.4/faq/programming.html#is-there-a-source-code-level-debugger-with-breakpoints-single-stepping-etc)16    - [Существует ли инструмент для поиска ошибок или выполнения статического анализа?](https://python-all.ru/3.4/faq/programming.html#is-there-a-tool-to-help-find-bugs-or-perform-static-analysis)17    - [Как создать автономный исполняемый файл из скрипта Python?](https://python-all.ru/3.4/faq/programming.html#how-can-i-create-a-stand-alone-binary-from-a-python-script)18    - [Существуют ли стандарты кодирования или руководство по стилю для программ на Python?](https://python-all.ru/3.4/faq/programming.html#are-there-coding-standards-or-a-style-guide-for-python-programs)19  - [Ядро языка](https://python-all.ru/3.4/faq/programming.html#core-language)2021    - [Почему возникает UnboundLocalError, если переменная имеет значение?](https://python-all.ru/3.4/faq/programming.html#why-am-i-getting-an-unboundlocalerror-when-the-variable-has-a-value)22    - [Каковы правила для локальных и глобальных переменных в Python?](https://python-all.ru/3.4/faq/programming.html#what-are-the-rules-for-local-and-global-variables-in-python)23    - [Почему лямбда-функции, определённые в цикле с разными значениями, возвращают один и тот же результат?](https://python-all.ru/3.4/faq/programming.html#why-do-lambdas-defined-in-a-loop-with-different-values-all-return-the-same-result)24    - [Как разделять глобальные переменные между модулями?](https://python-all.ru/3.4/faq/programming.html#how-do-i-share-global-variables-across-modules)25    - [Каковы «лучшие практики» использования import в модуле?](https://python-all.ru/3.4/faq/programming.html#what-are-the-best-practices-for-using-import-in-a-module)26    - [Почему значения по умолчанию разделяются между объектами?](https://python-all.ru/3.4/faq/programming.html#why-are-default-values-shared-between-objects)27    - [Как передать необязательные или именованные параметры из одной функции в другую?](https://python-all.ru/3.4/faq/programming.html#how-can-i-pass-optional-or-keyword-parameters-from-one-function-to-another)28    - [В чём разница между аргументами и параметрами?](https://python-all.ru/3.4/faq/programming.html#what-is-the-difference-between-arguments-and-parameters)29    - [Почему изменение списка 'y' также изменило список 'x'?](https://python-all.ru/3.4/faq/programming.html#why-did-changing-list-y-also-change-list-x)30    - [Как написать функцию с выходными параметрами (передача по ссылке)?](https://python-all.ru/3.4/faq/programming.html#how-do-i-write-a-function-with-output-parameters-call-by-reference)31    - [Как создать функцию высшего порядка в Python?](https://python-all.ru/3.4/faq/programming.html#how-do-you-make-a-higher-order-function-in-python)32    - [Как скопировать объект в Python?](https://python-all.ru/3.4/faq/programming.html#how-do-i-copy-an-object-in-python)33    - [Как найти методы или атрибуты объекта?](https://python-all.ru/3.4/faq/programming.html#how-can-i-find-the-methods-or-attributes-of-an-object)34    - [Как моему коду узнать имя объекта?](https://python-all.ru/3.4/faq/programming.html#how-can-my-code-discover-the-name-of-an-object)35    - [Что не так с приоритетом оператора запятой?](https://python-all.ru/3.4/faq/programming.html#what-s-up-with-the-comma-operator-s-precedence)36    - [Существует ли эквивалент тернарного оператора ”?:” из C?](https://python-all.ru/3.4/faq/programming.html#is-there-an-equivalent-of-c-s-ternary-operator)37    - [Можно ли писать запутанные однострочники на Python?](https://python-all.ru/3.4/faq/programming.html#is-it-possible-to-write-obfuscated-one-liners-in-python)38  - [Числа и строки](https://python-all.ru/3.4/faq/programming.html#numbers-and-strings)3940    - [Как указать шестнадцатеричные и восьмеричные целые числа?](https://python-all.ru/3.4/faq/programming.html#how-do-i-specify-hexadecimal-and-octal-integers)41    - [Почему -22 // 10 возвращает -3?](https://python-all.ru/3.4/faq/programming.html#why-does-22-10-return-3)42    - [Как преобразовать строку в число?](https://python-all.ru/3.4/faq/programming.html#how-do-i-convert-a-string-to-a-number)43    - [Как преобразовать число в строку?](https://python-all.ru/3.4/faq/programming.html#how-do-i-convert-a-number-to-a-string)44    - [Как изменить строку на месте?](https://python-all.ru/3.4/faq/programming.html#how-do-i-modify-a-string-in-place)45    - [Как с помощью строк вызывать функции и методы?](https://python-all.ru/3.4/faq/programming.html#how-do-i-use-strings-to-call-functions-methods)46    - [Существует ли аналог функции chomp() из Perl для удаления завершающих символов новой строки из строк?](https://python-all.ru/3.4/faq/programming.html#is-there-an-equivalent-to-perl-s-chomp-for-removing-trailing-newlines-from-strings)47    - [Существует ли аналог функций scanf() или sscanf()?](https://python-all.ru/3.4/faq/programming.html#is-there-a-scanf-or-sscanf-equivalent)48    - [Что означает ошибка UnicodeDecodeError или UnicodeEncodeError?](https://python-all.ru/3.4/faq/programming.html#what-does-unicodedecodeerror-or-unicodeencodeerror-error-mean)49  - [Производительность](https://python-all.ru/3.4/faq/programming.html#performance)5051    - [Моя программа слишком медленная. Как её ускорить?](https://python-all.ru/3.4/faq/programming.html#my-program-is-too-slow-how-do-i-speed-it-up)52    - [Какой способ конкатенации множества строк самый эффективный?](https://python-all.ru/3.4/faq/programming.html#what-is-the-most-efficient-way-to-concatenate-many-strings-together)53  - [Последовательности (кортежи/списки)](https://python-all.ru/3.4/faq/programming.html#sequences-tuples-lists)5455    - [Как преобразовывать кортежи в списки и обратно?](https://python-all.ru/3.4/faq/programming.html#how-do-i-convert-between-tuples-and-lists)56    - [Что такое отрицательный индекс?](https://python-all.ru/3.4/faq/programming.html#what-s-a-negative-index)57    - [Как перебрать последовательность в обратном порядке?](https://python-all.ru/3.4/faq/programming.html#how-do-i-iterate-over-a-sequence-in-reverse-order)58    - [Как удалить дубликаты из списка?](https://python-all.ru/3.4/faq/programming.html#how-do-you-remove-duplicates-from-a-list)59    - [Как создать массив в Python?](https://python-all.ru/3.4/faq/programming.html#how-do-you-make-an-array-in-python)60    - [Как создать многомерный список?](https://python-all.ru/3.4/faq/programming.html#how-do-i-create-a-multidimensional-list)61    - [Как применить метод к последовательности объектов?](https://python-all.ru/3.4/faq/programming.html#how-do-i-apply-a-method-to-a-sequence-of-objects)62    - [Почему a\_tuple\[i\] += \[‘item’\] вызывает исключение, хотя само сложение работает?](https://python-all.ru/3.4/faq/programming.html#why-does-a-tuple-i-item-raise-an-exception-when-the-addition-works)63  - [Словари](https://python-all.ru/3.4/faq/programming.html#dictionaries)6465    - [Как сделать, чтобы словарь хранил и выводил ключи в фиксированном порядке?](https://python-all.ru/3.4/faq/programming.html#how-can-i-get-a-dictionary-to-store-and-display-its-keys-in-a-consistent-order)66    - [Я хочу выполнить сложную сортировку: можно ли в Python реализовать преобразование Шварца?](https://python-all.ru/3.4/faq/programming.html#i-want-to-do-a-complicated-sort-can-you-do-a-schwartzian-transform-in-python)67    - [Как отсортировать один список по значениям из другого списка?](https://python-all.ru/3.4/faq/programming.html#how-can-i-sort-one-list-by-values-from-another-list)68  - [Объекты](https://python-all.ru/3.4/faq/programming.html#objects)6970    - [Что такое класс?](https://python-all.ru/3.4/faq/programming.html#what-is-a-class)71    - [Что такое метод?](https://python-all.ru/3.4/faq/programming.html#what-is-a-method)72    - [Что такое self?](https://python-all.ru/3.4/faq/programming.html#what-is-self)73    - [Как проверить, является ли объект экземпляром данного класса или его подкласса?](https://python-all.ru/3.4/faq/programming.html#how-do-i-check-if-an-object-is-an-instance-of-a-given-class-or-of-a-subclass-of-it)74    - [Что такое делегирование?](https://python-all.ru/3.4/faq/programming.html#what-is-delegation)75    - [Как вызвать метод, определённый в базовом классе, из производного класса, который его переопределяет?](https://python-all.ru/3.4/faq/programming.html#how-do-i-call-a-method-defined-in-a-base-class-from-a-derived-class-that-overrides-it)76    - [Как организовать код, чтобы было проще изменить базовый класс?](https://python-all.ru/3.4/faq/programming.html#how-can-i-organize-my-code-to-make-it-easier-to-change-the-base-class)77    - [Как создать статические данные класса и статические методы класса?](https://python-all.ru/3.4/faq/programming.html#how-do-i-create-static-class-data-and-static-class-methods)78    - [Как перегрузить конструкторы (или методы) в Python?](https://python-all.ru/3.4/faq/programming.html#how-can-i-overload-constructors-or-methods-in-python)79    - [Я пытаюсь использовать \_\_spam и получаю ошибку о \_SomeClassName\_\_spam.](https://python-all.ru/3.4/faq/programming.html#i-try-to-use-spam-and-i-get-an-error-about-someclassname-spam)80    - [Мой класс определяет \_\_del\_\_, но он не вызывается при удалении объекта.](https://python-all.ru/3.4/faq/programming.html#my-class-defines-del-but-it-is-not-called-when-i-delete-the-object)81    - [Как получить список всех экземпляров данного класса?](https://python-all.ru/3.4/faq/programming.html#how-do-i-get-a-list-of-all-instances-of-a-given-class)82    - [Почему результат `id()` кажется неуникальным?](https://python-all.ru/3.4/faq/programming.html#why-does-the-result-of-id-appear-to-be-not-unique)83  - [Модули](https://python-all.ru/3.4/faq/programming.html#modules)8485    - [Как создать .pyc-файл?](https://python-all.ru/3.4/faq/programming.html#how-do-i-create-a-pyc-file)86    - [Как узнать имя текущего модуля?](https://python-all.ru/3.4/faq/programming.html#how-do-i-find-the-current-module-name)87    - [Как сделать так, чтобы модули импортировали друг друга?](https://python-all.ru/3.4/faq/programming.html#how-can-i-have-modules-that-mutually-import-each-other)88    - [\_\_import\_\_(‘x.y.z’) возвращает \<module ‘x’\>; как получить z?](https://python-all.ru/3.4/faq/programming.html#import-x-y-z-returns-module-x-how-do-i-get-z)89    - [При редактировании импортированного модуля и его повторном импорте изменения не отображаются. Почему это происходит?](https://python-all.ru/3.4/faq/programming.html#when-i-edit-an-imported-module-and-reimport-it-the-changes-don-t-show-up-why-does-this-happen)9091## [Общие вопросы](https://python-all.ru/3.4/faq/programming.html#id2)9293### [Существует ли отладчик на уровне исходного кода с точками останова, пошаговым выполнением и т. д.?](https://python-all.ru/3.4/faq/programming.html#id3)9495Да.9697The pdb module is a simple but adequate console-mode debugger for Python. It is part of the standard Python library, and is [`documented in the Library Reference Manual`](https://python-all.ru/3.4/library/pdb.html#module-pdb). You can also write your own debugger by using the code for pdb as an example.9899Интерактивная среда разработки IDLE, которая входит в стандартную установку Python (обычно доступна как Tools/scripts/idle), включает графический отладчик.100101PythonWin – это IDE для Python, включающая графический отладчик на основе pdb. Отладчик PythonWin подсвечивает точки останова и обладает рядом полезных возможностей, например отладкой программ, не использующих PythonWin. PythonWin доступен как часть проекта [Python for Windows Extensions](https://python-all.ru/3.4/faq/programming.html), а также как часть дистрибутива ActivePython (см. [http://www.activestate.com/activepython](https://python-all.ru/3.4/faq/programming.html)).102103[Boa Constructor](https://python-all.ru/3.4/faq/programming.html) – это среда разработки и конструктор графического интерфейса на основе wxWidgets. Он предоставляет визуальное создание и редактирование фреймов, инспектор объектов, различные представления исходного кода, включая обозреватели объектов, иерархии наследования, HTML-документацию, сгенерированную из строк документации, расширенный отладчик, встроенную справку и поддержку Zope.104105[Eric](https://python-all.ru/3.4/faq/programming.html) – это IDE, построенная на PyQt и компоненте редактирования Scintilla.106107Pydb – это версия стандартного отладчика Python pdb, модифицированная для использования с DDD (Data Display Debugger) – популярным графическим интерфейсом отладчика. Pydb можно найти по адресу [http://bashdb.sourceforge.net/pydb/](https://python-all.ru/3.4/faq/programming.html), а DDD – по адресу [http://www.gnu.org/software/ddd](https://python-all.ru/3.4/faq/programming.html).108109Существует ряд коммерческих IDE для Python, включающих графические отладчики. Среди них:110111- Wing IDE ([http://wingware.com/](https://python-all.ru/3.4/faq/programming.html))112- Komodo IDE ([http://komodoide.com/](https://python-all.ru/3.4/faq/programming.html))113- PyCharm ([https://www.jetbrains.com/pycharm/](https://python-all.ru/3.4/faq/programming.html))114115### [Существует ли инструмент для поиска ошибок или выполнения статического анализа?](https://python-all.ru/3.4/faq/programming.html#id4)116117Да.118119PyChecker – это инструмент статического анализа, который находит ошибки в исходном коде Python и предупреждает о сложности и стиле кода. PyChecker можно получить по адресу [http://pychecker.sourceforge.net/](https://python-all.ru/3.4/faq/programming.html).120121[Pylint](https://python-all.ru/3.4/faq/programming.html) – это еще один инструмент, который проверяет, соответствует ли модуль стандарту кодирования, а также позволяет писать плагины для добавления пользовательских функций. В дополнение к проверке ошибок, которую выполняет PyChecker, Pylint предлагает дополнительные возможности, такие как проверка длины строк, правильности имен переменных в соответствии со стандартом кодирования, полноты реализации объявленных интерфейсов и многое другое. На [http://docs.pylint.org/](https://python-all.ru/3.4/faq/programming.html) приведен полный список функций Pylint.122123### [Как создать автономный исполняемый файл из скрипта Python?](https://python-all.ru/3.4/faq/programming.html#id5)124125Вам не нужно уметь компилировать Python в C, если ваша цель – создать автономную программу, которую пользователи могут скачать и запустить без предварительной установки дистрибутива Python. Существует ряд инструментов, которые определяют набор модулей, необходимых программе, и связывают эти модули вместе с бинарным файлом Python, создавая единый исполняемый файл.126127Один из способов – использовать инструмент freeze, который входит в исходный код Python как `Tools/freeze`. Он преобразует байт-код Python в массивы C; с помощью компилятора C вы можете встроить все свои модули в новую программу, которая затем связывается со стандартными модулями Python.128129Он работает, рекурсивно сканируя ваш исходный код на наличие операторов import (в обеих формах) и ищет модули в стандартном пути Python, а также в каталоге исходного кода (для встроенных модулей). Затем он превращает байт-код модулей, написанных на Python, в код C (инициализаторы массивов, которые можно превратить в объекты кода с помощью модуля marshal) и создает специальный конфигурационный файл, содержащий только те встроенные модули, которые действительно используются в программе. После этого он компилирует сгенерированный код C и компонует его с остальной частью интерпретатора Python, формируя самодостаточный бинарный файл, который ведет себя точно так же, как ваш скрипт.130131Очевидно, freeze требует компилятор C. Существует несколько других утилит, которые не требуют. Одна из них – py2exe Томаса Хеллера (только для Windows) по адресу132133> [http://www.py2exe.org/](https://python-all.ru/3.4/faq/programming.html)134135Другой инструмент – [cx\_Freeze](https://python-all.ru/3.4/faq/programming.html) Энтони Туйнинги.136137### [Существуют ли стандарты кодирования или руководство по стилю для программ на Python?](https://python-all.ru/3.4/faq/programming.html#id6)138139Да. Требуемый стиль оформления кода для модулей стандартной библиотеки описан в документе [**PEP 8**](https://python-all.ru/3.4/faq/programming.html).140141## [Ядро языка](https://python-all.ru/3.4/faq/programming.html#id7)142143### [Почему возникает UnboundLocalError, если переменная содержит значение?](https://python-all.ru/3.4/faq/programming.html#id8)144145Может быть неожиданным получить ошибку UnboundLocalError в ранее работавшем коде после добавления оператора присваивания где-то в теле функции.146147Этот код:148149```python150>>> x = 10151>>> def bar():152...     print(x)153>>> bar()15410155```156157работает, но этот код:158159```python160>>> x = 10161>>> def foo():162...     print(x)163...     x += 1164```165166приводит к ошибке UnboundLocalError:167168```python169>>> foo()170Traceback (most recent call last):171  ...172UnboundLocalError: local variable 'x' referenced before assignment173```174175Это происходит потому, что когда вы присваиваете значение переменной в некоторой области видимости, эта переменная становится локальной для этой области и скрывает любую одноимённую переменную из внешней области. Поскольку последний оператор в foo присваивает новое значение `x`, компилятор распознаёт её как локальную переменную. Следовательно, когда более ранний `print(x)` пытается вывести неинициализированную локальную переменную, возникает ошибка.176177В приведённом выше примере можно получить доступ к переменной внешней области, объявив её глобальной:178179```python180>>> x = 10181>>> def foobar():182...     global x183...     print(x)184...     x += 1185>>> foobar()18610187```188189Такое явное объявление необходимо, чтобы напомнить: в отличие от внешне похожей ситуации с переменными класса и экземпляра, здесь фактически изменяется значение переменной во внешней области видимости:190191```python192>>> print(x)19311194```195196Аналогичное действие можно выполнить во вложенной области видимости с помощью ключевого слова [`nonlocal`](https://python-all.ru/3.4/reference/simple_stmts.html#nonlocal):197198```python199>>> def foo():200...    x = 10201...    def bar():202...        nonlocal x203...        print(x)204...        x += 1205...    bar()206...    print(x)207>>> foo()2081020911210```211212### [Каковы правила использования локальных и глобальных переменных в Python?](https://python-all.ru/3.4/faq/programming.html#id9)213214В Python переменные, на которые только ссылаются внутри функции, неявно считаются глобальными. Если переменной присваивается значение где-либо в теле функции, она считается локальной, если явно не объявлена как global.215216Хотя сначала это может показаться удивительным, небольшое размышление всё объясняет. С одной стороны, требование [`global`](https://python-all.ru/3.4/reference/simple_stmts.html#global) для присваиваемых переменных предотвращает непреднамеренные побочные эффекты. С другой стороны, если бы `global` требовалось для всех глобальных ссылок, вам пришлось бы использовать `global` постоянно. Пришлось бы объявлять как глобальные каждую ссылку на встроенную функцию или компонент импортированного модуля. Такой беспорядок свёл бы на нет полезность объявления `global` для выявления побочных эффектов.217218### [Почему лямбды, определённые в цикле с разными значениями, все возвращают один и тот же результат?](https://python-all.ru/3.4/faq/programming.html#id10)219220Предположим, что с помощью цикла for определяется несколько разных лямбд (или даже обычных функций), например:221222```python223>>> squares = []224>>> for x in range(5):225...    squares.append(lambda: x**2)226```227228В результате получается список, содержащий 5 лямбда-функций, вычисляющих `x**2`. Можно ожидать, что при вызове они вернут соответственно `0`, `1`, `4`, `9` и `16`. Однако когда вы попробуете, то увидите, что все они возвращают `16`:229230```python231>>> squares[2]()23216233>>> squares[4]()23416235```236237Это происходит потому, что `x` не является локальной для лямбда-функций, а определена во внешней области видимости и доступна при вызове лямбды, а не при её определении. В конце цикла значение `x` равно `4`, поэтому все функции теперь возвращают `4**2`, то есть `16`. Вы также можете убедиться в этом, изменив значение `x` и посмотрев, как изменятся результаты лямбд:238239```python240>>> x = 8241>>> squares[2]()24264243```244245Чтобы избежать этого, нужно сохранить значения в переменных, локальных для лямбд, чтобы они не зависели от значения глобальной `x`:246247```python248>>> squares = []249>>> for x in range(5):250...    squares.append(lambda n=x: n**2)251```252253Здесь `n=x` создаёт новую переменную `n`, локальную для лямбды и вычисляемую при её определении, так что она имеет то же значение, что и `x` в тот момент цикла. Это означает, что значение `n` будет равно `0` в первой лямбде, `1` во второй, `2` в третьей и так далее. Следовательно, каждая лямбда теперь вернёт правильный результат:254255```python256>>> squares[2]()2574258>>> squares[4]()25916260```261262Обратите внимание: такое поведение присуще не только лямбдам, но и обычным функциям.263264### [Как разделять глобальные переменные между модулями?](https://python-all.ru/3.4/faq/programming.html#id11)265266Общепринятый способ обмена информацией между модулями в рамках одной программы – создать специальный модуль (часто называемый config или cfg). Достаточно импортировать модуль config во все модули приложения, и он станет доступен как глобальное имя. Поскольку у каждого модуля существует только один экземпляр, любые изменения объекта модуля отражаются везде. Например:267268config.py:269270```python271x = 0   # Значение по умолчанию для параметра конфигурации 'x'272```273274mod.py:275276```python277import config278config.x = 1279```280281main.py:282283```python284import config285import mod286print(config.x)287```288289Обратите внимание: использование модуля также является основой для реализации паттерна Singleton по той же причине.290291### [Каковы «лучшие практики» использования import в модуле?](https://python-all.ru/3.4/faq/programming.html#id12)292293В общем случае не используйте `from modulename import *`. Это засоряет пространство имён импортирующего модуля и значительно усложняет линтерам обнаружение неопределённых имён.294295Импортируйте модули в начале файла. Так сразу становится ясно, какие ещё модули требуются вашему коду, и не возникает вопросов, находится ли имя модуля в области видимости. Использование одного импорта на строку упрощает добавление и удаление импортов, а использование нескольких импортов в одной строке экономит место на экране.296297Рекомендуется импортировать модули в следующем порядке:2982991. модули стандартной библиотеки – например, `sys`, `os`, `getopt`, `re`3002. модули сторонних библиотек (всё, установленное в каталог site-packages Python), например mx.DateTime, ZODB, PIL.Image и т.д.3013. модули локальной разработки302303Иногда импорты приходится переносить внутрь функции или класса, чтобы избежать проблем с циклическими импортами. Gordon McMillan говорит:304305> Циклические импорты нормально работают, когда оба модуля используют форму импорта “import \<module\>”. Они перестают работать, когда второй модуль пытается получить имя из первого (“from module import name”), и импорт находится на верхнем уровне. Это происходит потому, что имена в первом модуле ещё недоступны, так как первый модуль занят импортом второго.306307В этом случае, если второй модуль используется только в одной функции, импорт можно легко перенести в эту функцию. К моменту вызова импорта первый модуль уже завершит инициализацию, и второй модуль сможет выполнить свой импорт.308309Также может потребоваться перенести импорты из верхнего уровня кода, если некоторые модули являются платформозависимыми. В таком случае может быть невозможно импортировать все модули в начале файла. Тогда хорошим решением будет импортировать нужные модули в соответствующем платформозависимом коде.310311Переносите импорты в локальную область видимости, например внутрь определения функции, только если это необходимо для решения проблемы, такой как избежание циклического импорта или попытка сократить время инициализации модуля. Этот метод особенно полезен, если многие импорты не нужны в зависимости от того, как выполняется программа. Возможно, вы также захотите перенести импорты в функцию, если модули используются только внутри неё. Обратите внимание, что загрузка модуля в первый раз может быть дорогой из-за однократной инициализации модуля, но повторная загрузка модуля практически бесплатна – требуется лишь несколько поисков в словаре. Даже если имя модуля вышло из области видимости, модуль, вероятно, доступен в [`sys.modules`](https://python-all.ru/3.4/library/sys.html#sys.modules).312313### [Почему значения по умолчанию являются общими для объектов?](https://python-all.ru/3.4/faq/programming.html#id13)314315Подобная ошибка часто подстерегает начинающих программистов. Рассмотрим следующую функцию:316317```python318def foo(mydict={}):  # Опасность: общая ссылка на один словарь для всех вызовов319    ... compute something ...320    mydict[key] = value321    return mydict322```323324При первом вызове этой функции `mydict` содержит один элемент. Во второй раз `mydict` содержит два элемента, потому что когда `foo()` начинает выполняться, `mydict` уже содержит один элемент.325326Часто ожидается, что при вызове функции для значений по умолчанию создаются новые объекты. Но это не так. Значения по умолчанию создаются ровно один раз, при определении функции. Если этот объект изменяется (как словарь в данном примере), то последующие вызовы функции будут обращаться к этому изменённому объекту.327328По определению, неизменяемые объекты, такие как числа, строки, кортежи и `None`, защищены от изменений. Изменения изменяемых объектов, таких как словари, списки и экземпляры классов, могут привести к путанице.329330Из-за этой особенности рекомендуется не использовать изменяемые объекты в качестве значений по умолчанию. Вместо этого используйте `None` в качестве значения по умолчанию, а внутри функции проверяйте, равен ли параметр `None`, и создавайте новый список/словарь/что угодно, если это так. Например, не пишите:331332```python333def foo(mydict={}):334    ...335```336337а:338339```python340def foo(mydict=None):341    if mydict is None:342        mydict = {}  # создать новый словарь для локального пространства имён343```344345Эта возможность может быть полезной. Если есть функция, вычисление которой требует много времени, распространённый приём – кэшировать параметры и результат каждого вызова функции, а при повторном запросе тех же значений возвращать сохранённый результат. Это называется «мемоизация» и может быть реализовано так:346347```python348# Вызывающие никогда не передадут третий параметр этой функции.349def expensive(arg1, arg2, _cache={}):350    if (arg1, arg2) in _cache:351        return _cache[(arg1, arg2)]352353    # Вычислить значение354    result = ... expensive computation ...355    _cache[(arg1, arg2)] = result           # Сохранить результат в кеше356    return result357```358359Вместо значения по умолчанию можно использовать глобальную переменную со словарём; это дело вкуса.360361### [Как передать необязательные или именованные параметры из одной функции в другую?](https://python-all.ru/3.4/faq/programming.html#id14)362363Соберите аргументы с помощью спецификаторов `*` и `**` в списке параметров функции; это даст позиционные аргументы в виде кортежа, а именованные – в виде словаря. Затем вы можете передать эти аргументы при вызове другой функции, используя `*` и `**`:364365```python366def f(x, *args, **kwargs):367    ...368    kwargs['width'] = '14.3c'369    ...370    g(x, *args, **kwargs)371```372373### [В чём разница между аргументами и параметрами?](https://python-all.ru/3.4/faq/programming.html#id15)374375[*Параметры*](https://python-all.ru/3.4/glossary.html#term-parameter) определяются именами, которые указаны в определении функции, тогда как [*аргументы*](https://python-all.ru/3.4/glossary.html#term-argument) – это значения, которые передаются функции при её вызове. Параметры определяют, какие типы аргументов может принимать функция. Например, для такого определения функции:376377```python378def func(foo, bar=None, **kwargs):379    pass380```381382*foo*, *bar* и *kwargs* – это параметры `func`. Однако при вызове `func`, например:383384```python385func(42, bar=314, extra=somevar)386```387388значения `42`, `314` и `somevar` являются аргументами.389390### [Почему изменение списка ‘y’ также изменило список ‘x’?](https://python-all.ru/3.4/faq/programming.html#id16)391392Если вы написали такой код:393394```python395>>> x = []396>>> y = x397>>> y.append(10)398>>> y399[10]400>>> x401[10]402```403404вас может интересовать, почему добавление элемента в `y` изменило также и `x`.405406К этому результату приводят два фактора:4074081. Переменные – это просто имена, ссылающиеся на объекты. Присваивание `y = x` не создаёт копию списка – оно создаёт новую переменную `y`, которая ссылается на тот же объект, на который ссылается `x`. Это означает, что существует только один объект (список), и обе переменные `x` и `y` ссылаются на него.4092. Списки являются [*изменяемыми*](https://python-all.ru/3.4/glossary.html#term-mutable), то есть их содержимое можно изменять.410411После вызова `append()` содержимое изменяемого объекта изменилось с `[]` на `[10]`. Поскольку обе переменные ссылаются на один и тот же объект, использование любого имени даёт доступ к изменённому значению `[10]`.412413Если же присвоить неизменяемый объект `x`:414415```python416>>> x = 5  # int – неизменяемый тип417>>> y = x418>>> x = x + 1  # 5 нельзя изменить, здесь создаётся новый объект419>>> x4206421>>> y4225423```424425в этом случае `x` и `y` уже не равны. Это связано с тем, что целые числа [*неизменяемы*](https://python-all.ru/3.4/glossary.html#term-immutable): когда мы пишем `x = x + 1`, мы не изменяем int `5`, увеличивая его значение; вместо этого мы создаём новый объект (int `6`) и присваиваем его `x` (то есть меняем, на какой объект ссылается `x`). После этого присваивания у нас есть два объекта (int `6` и `5`) и две переменные, которые на них ссылаются (`x` теперь ссылается на `6`, а `y` по-прежнему ссылается на `5`).426427Некоторые операции (например, `y.append(10)` и `y.sort()`) изменяют объект, тогда как внешне похожие операции (например, `y = y + [10]` и `sorted(y)`) создают новый объект. В целом в Python (и во всех случаях в стандартной библиотеке) метод, который изменяет объект, возвращает `None`, чтобы помочь не путать два типа операций. Так что если вы по ошибке напишете `y.sort()`, полагая, что он даст отсортированную копию `y`, вы вместо этого получите `None`, что, скорее всего, приведет к легко диагностируемой ошибке в вашей программе.428429Однако есть один класс операций, где одна и та же операция иногда ведет себя по-разному для разных типов: составные операторы присваивания (augmented assignment). Например, `+=` изменяет списки, но не кортежи или int (`a_list += [1, 2, 3]` эквивалентно `a_list.extend([1, 2, 3])` и изменяет `a_list`, тогда как `some_tuple += (1, 2, 3)` и `some_int += 1` создают новые объекты).430431Иными словами:432433- Если у нас есть изменяемый объект ([`list`](https://python-all.ru/3.4/library/stdtypes.html#list), [`dict`](https://python-all.ru/3.4/library/stdtypes.html#dict), [`set`](https://python-all.ru/3.4/library/stdtypes.html#set) и т.д.), мы можем использовать некоторые специфические операции, чтобы изменить его, и все переменные, которые на него ссылаются, увидят это изменение.434- Если у нас есть неизменяемый объект ([`str`](https://python-all.ru/3.4/library/stdtypes.html#str), [`int`](https://python-all.ru/3.4/library/functions.html#int), [`tuple`](https://python-all.ru/3.4/library/stdtypes.html#tuple) и т.д.), все переменные, которые на него ссылаются, всегда будут видеть одно и то же значение, но операции, преобразующие это значение в новое, всегда возвращают новый объект.435436Чтобы узнать, ссылаются ли две переменные на один и тот же объект, можно использовать оператор [`is`](https://python-all.ru/3.4/reference/expressions.html#is) или встроенную функцию [`id()`](https://python-all.ru/3.4/library/functions.html#id).437438### [Как написать функцию с выходными параметрами (передача по ссылке)?](https://python-all.ru/3.4/faq/programming.html#id17)439440Помните, что в Python аргументы передаются по присваиванию. Поскольку присваивание лишь создает ссылки на объекты, между именем аргумента в вызывающей и вызываемой функции нет псевдонима, а значит, нет и передачи по ссылке как таковой. Желаемого эффекта можно достичь несколькими способами.4414421. Возвращая кортеж результатов:443444   ```python445   def func2(a, b):446       a = 'new-value'        # a и b – локальные имена447       b = b + 1              # присвоены новым объектам448       return a, b            # вернуть новые значения449450   x, y = 'old-value', 99451   x, y = func2(x, y)452   print(x, y)                # вывод: new-value 100453   ```454455   Это почти всегда самое понятное решение.4562. С помощью глобальных переменных. Это не потокобезопасно и не рекомендуется.4573. Передавая изменяемый (изменяемый на месте) объект:458459   ```python460   def func1(a):461       a[0] = 'new-value'     # 'a' ссылается на изменяемый список462       a[1] = a[1] + 1        # изменяет общий объект463464   args = ['old-value', 99]465   func1(args)466   print(args[0], args[1])    # вывод: new-value 100467   ```4684. Передавая словарь, который будет изменён:469470   ```python471   def func3(args):472       args['a'] = 'new-value'     # args – изменяемый словарь473       args['b'] = args['b'] + 1   # изменить его на месте474475   args = {'a':' old-value', 'b': 99}476   func3(args)477   print(args['a'], args['b'])478   ```4795. Или объединив значения в экземпляре класса:480481   ```python482   class callByRef:483       def __init__(self, **args):484           for (key, value) in args.items():485               setattr(self, key, value)486487   def func4(args):488       args.a = 'new-value'        # args – изменяемый callByRef489       args.b = args.b + 1         # изменить объект на месте490491   args = callByRef(a='old-value', b=99)492   func4(args)493   print(args.a, args.b)494   ```495496   Почти никогда нет веской причины усложнять до такой степени.497498Лучший выбор – вернуть кортеж, содержащий несколько результатов.499500### [Как сделать функцию высшего порядка в Python?](https://python-all.ru/3.4/faq/programming.html#id18)501502У вас есть два варианта: использовать вложенные области видимости или вызываемые объекты. Например, предположим, вы хотите определить `linear(a,b)`, которая возвращает функцию `f(x)`, вычисляющую значение `a*x+b`. Использование вложенных областей видимости:503504```python505def linear(a, b):506    def result(x):507        return a * x + b508    return result509```510511Или используя вызываемый объект:512513```python514class linear:515516    def __init__(self, a, b):517        self.a, self.b = a, b518519    def __call__(self, x):520        return self.a * x + self.b521```522523В обоих случаях524525```python526taxes = linear(0.3, 2)527```528529даёт вызываемый объект, где `taxes(10e6) == 0.3 * 10e6 + 2`.530531Подход с вызываемым объектом имеет недостаток: он немного медленнее и\\nприводит к чуть более длинному коду. Однако обратите внимание, что набор вызываемых объектов\\nможет разделять свою сигнатуру через наследование:532533```python534class exponential(linear):535    # __init__ унаследован536    def __call__(self, x):537        return self.a * (x ** self.b)538```539540Объект может инкапсулировать состояние для нескольких методов:541542```python543class counter:544545    value = 0546547    def set(self, x):548        self.value = x549550    def up(self):551        self.value = self.value + 1552553    def down(self):554        self.value = self.value - 1555556count = counter()557inc, dec, reset = count.up, count.down, count.set558```559560Здесь `inc()`, `dec()` и `reset()` ведут себя как функции, которые совместно используют одну и ту же переменную-счётчик.561562### [Как скопировать объект в Python?](https://python-all.ru/3.4/faq/programming.html#id19)563564В общем случае попробуйте [`copy.copy()`](https://python-all.ru/3.4/library/copy.html#copy.copy) или [`copy.deepcopy()`](https://python-all.ru/3.4/library/copy.html#copy.deepcopy). Не все объекты можно копировать, но большинство можно.565566Некоторые объекты копировать проще. У словарей есть метод [`copy()`](https://python-all.ru/3.4/library/stdtypes.html#dict.copy):567568```python569newdict = olddict.copy()570```571572Последовательности можно скопировать срезом:573574```python575new_l = l[:]576```577578### [Как найти методы или атрибуты объекта?](https://python-all.ru/3.4/faq/programming.html#id20)579580Для экземпляра x пользовательского класса `dir(x)` возвращает отсортированный по алфавиту список имён, содержащий атрибуты экземпляра, а также методы и атрибуты, определённые в его классе.581582### [Как код может узнать имя объекта?](https://python-all.ru/3.4/faq/programming.html#id21)583584Вообще говоря, нет, потому что у объектов на самом деле нет имён. По сути, присваивание всегда связывает имя со значением; то же верно для инструкций `def` и `class`, но в этом случае значением является вызываемый объект. Рассмотрим следующий код:585586```python587class A:588    pass589590B = A591592a = B()593b = a594print(b)595<__main__.A object at 0x16D07CC>596print(a)597<__main__.A object at 0x16D07CC>598```599600Можно утверждать, что у класса есть имя: даже если он привязан к двум именам и вызывается через имя B, созданный экземпляр всё равно будет определён как экземпляр класса A. Однако невозможно сказать, какое имя у экземпляра – a или b, поскольку оба имени привязаны к одному и тому же значению.601602Вообще говоря, коду не требуется «знать имена» конкретных значений. Если вы не пишете намеренно интроспективные программы, это обычно указывает на то, что стоит изменить подход.603604В comp.lang.python Фредрик Лунд однажды привёл отличную аналогию в ответ на этот вопрос:605606> Точно так же, как вы узнаёте имя кота, которого нашли на крыльце: сам кот (объект) не может сказать вам своего имени, и ему на это всё равно – так что единственный способ узнать, как его зовут, – спросить всех соседей (пространства имён), не их ли это кот (объект)...607>608> ...и не удивляйтесь, если окажется, что он известен под многими именами – или вообще без имени!609610### [Что не так с приоритетом оператора-запятой?](https://python-all.ru/3.4/faq/programming.html#id22)611612Запятая в Python – не оператор. Рассмотрим такой сеанс:613614```python615>>> "a" in "b", "a"616(False, 'a')617```618619Поскольку запятая – не оператор, а разделитель между выражениями, приведённый выше код выполняется так, как если бы вы ввели:620621```python622("a" in "b"), "a"623```624625а не:626627```python628"a" in ("b", "a")629```630631То же самое верно для различных операторов присваивания (`=`, `+=` и т. д.). Они не являются операторами в полном смысле, а представляют собой синтаксические разделители в операторах присваивания.632633### [Существует ли эквивалент тернарного оператора ”?:” из C?](https://python-all.ru/3.4/faq/programming.html#id23)634635Да, существует. Синтаксис следующий:636637```python638[on_true] if [expression] else [on_false]639640x, y = 50, 25641small = x if x < y else y642```643644До введения этого синтаксиса в Python 2.5 распространённым приёмом было использование логических операторов:645646```python647[expression] and [on_true] or [on_false]648```649650Однако этот приём небезопасен, так как может дать неверный результат, если *on\_true* имеет ложное булево значение. Поэтому всегда лучше использовать форму `... if ... else ...`.651652### [Можно ли писать запутанные однострочники на Python?](https://python-all.ru/3.4/faq/programming.html#id24)653654Да. Обычно это делается путём вложения [`lambda`](https://python-all.ru/3.4/reference/expressions.html#lambda) в [`lambda`](https://python-all.ru/3.4/reference/expressions.html#lambda). Смотрите следующие три примера, автор Ulf Bartelt:655656```python657from functools import reduce658659# Простые числа < 1000660print(list(filter(None,map(lambda y:y*reduce(lambda x,y:x*y!=0,661map(lambda x,y=y:y%x,range(2,int(pow(y,0.5)+1))),1),range(2,1000)))))662663# Первые 10 чисел Фибоначчи664print(list(map(lambda x,f=lambda x,f:(f(x-1,f)+f(x-2,f)) if x>1 else 1:665f(x,f), range(10))))666667# Множество Мандельброта668print((lambda Ru,Ro,Iu,Io,IM,Sx,Sy:reduce(lambda x,y:x+y,map(lambda y,669Iu=Iu,Io=Io,Ru=Ru,Ro=Ro,Sy=Sy,L=lambda yc,Iu=Iu,Io=Io,Ru=Ru,Ro=Ro,i=IM,670Sx=Sx,Sy=Sy:reduce(lambda x,y:x+y,map(lambda x,xc=Ru,yc=yc,Ru=Ru,Ro=Ro,671i=i,Sx=Sx,F=lambda xc,yc,x,y,k,f=lambda xc,yc,x,y,k,f:(k<=0)or (x*x+y*y672>=4.0) or 1+f(xc,yc,x*x-y*y+xc,2.0*x*y+yc,k-1,f):f(xc,yc,x,y,k,f):chr(67364+F(Ru+x*(Ro-Ru)/Sx,yc,0,0,i)),range(Sx))):L(Iu+y*(Io-Iu)/Sy),range(Sy674))))(-2.1, 0.7, -1.2, 1.2, 30, 80, 24))675#    \___ ___/  \___ ___/  |   |   |__ линии на экране676#        V          V      |   |______ столбцы на экране677#        |          |      |__________ максимум "iterations"678#        |          |_________________ диапазон по оси Y679#        |____________________________ диапазон по оси X680```681682Не пытайтесь повторить это дома, дети!683684## [Числа и строки](https://python-all.ru/3.4/faq/programming.html#id25)685686### [Как задать шестнадцатеричные и восьмеричные целые числа?](https://python-all.ru/3.4/faq/programming.html#id26)687688Чтобы задать восьмеричное число, поставьте перед восьмеричным значением ноль, а затем строчную или прописную букву «o». Например, чтобы присвоить переменной «a» восьмеричное значение «10» (8 в десятичной системе), введите:689690```python691>>> a = 0o10692>>> a6938694```695696Шестнадцатеричные числа задаются так же просто. Просто поставьте перед шестнадцатеричным числом ноль, а затем строчную или прописную «x». Шестнадцатеричные цифры можно указывать в нижнем или верхнем регистре. Например, в интерпретаторе Python:697698```python699>>> a = 0xa5700>>> a701165702>>> b = 0XB2703>>> b704178705```706707### [Почему -22 // 10 возвращает -3?](https://python-all.ru/3.4/faq/programming.html#id27)708709Это в первую очередь обусловлено желанием, чтобы `i % j` имел тот же знак, что и `j`. Если вы хотите этого, а также хотите:710711```python712i == (i // j) * j + (i % j)713```714715тогда целочисленное деление должно возвращать floor (целую часть с округлением вниз). C также требует выполнения этого тождества, и тогда компиляторы, которые обрезают `i // j`, должны сделать так, чтобы `i % j` имел тот же знак, что и `i`.716717Существует мало реальных случаев использования `i % j`, когда `j` отрицательно. Когда `j` положительно, таких случаев много, и практически во всех из них полезнее, чтобы `i % j` было равно `>= 0`. Если часы показывают 10 сейчас, что они показывали 200 часов назад? `-190 % 12 == 2` полезно; `-190 % 12 == -10` – это ошибка, которая только и ждёт, чтобы проявиться.718719### [Как преобразовать строку в число?](https://python-all.ru/3.4/faq/programming.html#id28)720721Для целых чисел используйте встроенный конструктор типа [`int()`](https://python-all.ru/3.4/library/functions.html#int), например `int('144') == 144`. Аналогично [`float()`](https://python-all.ru/3.4/library/functions.html#float) преобразует в число с плавающей точкой, например `float('144') == 144.0`.722723По умолчанию эти функции интерпретируют число как десятичное, так что `int('0144') == 144` и `int('0x144')` возбуждают [`ValueError`](https://python-all.ru/3.4/library/exceptions.html#ValueError). `int(string, base)` принимает основание системы счисления как второй необязательный аргумент, так что `int('0x144', 16) == 324`. Если основание указано как 0, число интерпретируется по правилам Python: ведущий '0o' обозначает восьмеричную систему, а '0x' – шестнадцатеричную.724725Не используйте встроенную функцию [`eval()`](https://python-all.ru/3.4/library/functions.html#eval), если вам нужно только преобразовать строки в числа. [`eval()`](https://python-all.ru/3.4/library/functions.html#eval) будет значительно медленнее и представляет угрозу безопасности: кто-то может передать вам Python-выражение с нежелательными побочными эффектами. Например, кто-то может передать `__import__('os').system("rm -rf $HOME")`, что удалит ваш домашний каталог.726727[`eval()`](https://python-all.ru/3.4/library/functions.html#eval) также интерпретирует числа как Python-выражения, так что, например, `eval('09')` вызывает синтаксическую ошибку, поскольку Python не допускает ведущий ноль в десятичных числах (кроме самого '0').728729### [Как преобразовать число в строку?](https://python-all.ru/3.4/faq/programming.html#id29)730731Чтобы преобразовать, например, число 144 в строку '144', используйте встроенный конструктор типа [`str()`](https://python-all.ru/3.4/library/stdtypes.html#str). Если нужна шестнадцатеричная или восьмеричная запись, используйте встроенные функции [`hex()`](https://python-all.ru/3.4/library/functions.html#hex) или [`oct()`](https://python-all.ru/3.4/library/functions.html#oct). Для сложного форматирования смотрите раздел [*Форматирование строк*](https://python-all.ru/3.4/library/string.html#string-formatting), например `"{:04d}".format(144)` даёт `'0144'`, а `"{:.3f}".format(1.0/3.0)` даёт `'0.333'`.732733### [Как изменить строку на месте?](https://python-all.ru/3.4/faq/programming.html#id30)734735Нельзя, потому что строки неизменяемы. В большинстве случаев следует просто собирать новую строку из нужных частей. Однако если вам нужен объект с возможностью изменять Unicode-данные на месте, попробуйте объект [`io.StringIO`](https://python-all.ru/3.4/library/io.html#io.StringIO) или модуль [`array`](https://python-all.ru/3.4/library/array.html#module-array):736737```python738>>> import io739>>> s = "Hello, world"740>>> sio = io.StringIO(s)741>>> sio.getvalue()742'Hello, world'743>>> sio.seek(7)7447745>>> sio.write("there!")7466747>>> sio.getvalue()748'Hello, there!'749750>>> import array751>>> a = array.array('u', s)752>>> print(a)753array('u', 'Hello, world')754>>> a[0] = 'y'755>>> print(a)756array('u', 'yello, world')757>>> a.tounicode()758'yello, world'759```760761### [Как использовать строки для вызова функций/методов?](https://python-all.ru/3.4/faq/programming.html#id31)762763Существует несколько приёмов.764765- Лучший из них – использовать словарь, сопоставляющий строки с функциями. Главное преимущество этого подхода в том, что строки не обязаны совпадать с именами функций. Это также основной способ эмуляции конструкции case:766767  ```python768  def a():769      pass770771  def b():772      pass773774  dispatch = {'go': a, 'stop': b}  # Обратите внимание на отсутствие скобок для функций775776  dispatch[get_input()]()  # Обратите внимание на завершающие скобки для вызова функции777  ```778- Используйте встроенную функцию [`getattr()`](https://python-all.ru/3.4/library/functions.html#getattr):779780  ```python781  import foo782  getattr(foo, 'bar')()783  ```784785  Обратите внимание, что [`getattr()`](https://python-all.ru/3.4/library/functions.html#getattr) работает с любым объектом, включая классы, экземпляры классов, модули и т.д.786787  Это используется в нескольких местах стандартной библиотеки, например:788789  ```python790  class Foo:791      def do_foo(self):792          ...793794      def do_bar(self):795          ...796797  f = getattr(foo_instance, 'do_' + opname)798  f()799  ```800- Используйте [`locals()`](https://python-all.ru/3.4/library/functions.html#locals) или [`eval()`](https://python-all.ru/3.4/library/functions.html#eval) для разрешения имени функции:801802  ```python803  def myFunc():804      print("hello")805806  fname = "myFunc"807808  f = locals()[fname]809  f()810811  f = eval(fname)812  f()813  ```814815  Примечание: использование [`eval()`](https://python-all.ru/3.4/library/functions.html#eval) медленно и опасно. Если у вас нет полного контроля над содержимым строки, кто-то может передать строку, которая приведёт к выполнению произвольной функции.816817### [Существует ли аналог функции chomp() из Perl для удаления завершающих символов новой строки из строк?](https://python-all.ru/3.4/faq/programming.html#id32)818819Вы можете использовать `S.rstrip("\r\n")`, чтобы удалить все символы конца строки из конца строки `S`, не удаляя при этом другие пробельные символы в конце. Если строка `S` содержит несколько строк с несколькими пустыми строками в конце, будут удалены символы конца строки для всех пустых строк:820821```python822>>> lines = ("line 1 \r\n"823...          "\r\n"824...          "\r\n")825>>> lines.rstrip("\n\r")826'line 1 '827```828829Так как это обычно требуется только при построчном чтении текста, использование `S.rstrip()` таким образом вполне эффективно.830831### [Существует ли аналог функций scanf() или sscanf()?](https://python-all.ru/3.4/faq/programming.html#id33)832833Прямого аналога нет.834835Для простого разбора ввода обычно проще всего разбить строку на слова, разделённые пробелами, с помощью метода [`split()`](https://python-all.ru/3.4/library/stdtypes.html#str.split) строковых объектов, а затем преобразовать десятичные строки в числа с помощью [`int()`](https://python-all.ru/3.4/library/functions.html#int) или [`float()`](https://python-all.ru/3.4/library/functions.html#float). `split()` поддерживает необязательный параметр "sep", который полезен, если строка использует не пробелы в качестве разделителя.836837Для более сложного разбора ввода регулярные выражения мощнее, чем `sscanf()` в C, и лучше подходят для этой задачи.838839### [Что означает ошибка UnicodeDecodeError или UnicodeEncodeError?](https://python-all.ru/3.4/faq/programming.html#id34)840841Смотрите [*Unicode HOWTO*](https://python-all.ru/3.4/howto/unicode.html#unicode-howto).842843## [Производительность](https://python-all.ru/3.4/faq/programming.html#id35)844845### [Моя программа слишком медленная. Как её ускорить?](https://python-all.ru/3.4/faq/programming.html#id36)846847В целом это непростой вопрос. Во-первых, вот список того, что стоит помнить, прежде чем углубляться:848849- Характеристики производительности различаются в разных реализациях Python. В этом FAQ основное внимание уделяется [*CPython*](https://python-all.ru/3.4/glossary.html#term-cpython).850- Поведение может различаться в разных операционных системах, особенно когда речь идёт о вводе-выводе или многопоточности.851- Следует всегда находить узкие места в программе *перед* попытками оптимизировать какой-либо код (см. модуль [`profile`](https://python-all.ru/3.4/library/profile.html#module-profile)).852- Написание бенчмарк-скриптов позволит быстро итерировать при поиске улучшений (см. модуль [`timeit`](https://python-all.ru/3.4/library/timeit.html#module-timeit)).853- Настоятельно рекомендуется иметь хорошее покрытие кода (с помощью модульного тестирования или любой другой методики) перед возможным внесением регрессий, скрытых в сложных оптимизациях.854855Тем не менее, есть много приёмов для ускорения кода на Python. Вот некоторые общие принципы, которые сильно помогают достичь приемлемого уровня производительности:856857- Ускорение алгоритмов (или замена на более быстрые) может принести гораздо большую выгоду, чем попытки рассыпать микрооптимизации по всему коду.858- Используйте правильные структуры данных. Изучите документацию по [*Встроенным типам*](https://python-all.ru/3.4/library/stdtypes.html#bltin-types) и модулю [`collections`](https://python-all.ru/3.4/library/collections.html#module-collections).859- Когда стандартная библиотека предоставляет примитив для выполнения какой-либо операции, он, скорее всего (хотя и не гарантированно), будет быстрее любой альтернативы, которую вы можете придумать. Это вдвойне верно для примитивов, написанных на C, таких как встроенные функции и некоторые расширенные типы. Например, обязательно используйте встроенный метод [`list.sort()`](https://python-all.ru/3.4/library/stdtypes.html#list.sort) или соответствующую функцию [`sorted()`](https://python-all.ru/3.4/library/functions.html#sorted) для сортировки (и посмотрите [*Sorting HOW TO*](https://python-all.ru/3.4/howto/sorting.html#sortinghowto) для примеров умеренно продвинутого использования).860- Абстракции обычно создают косвенность и заставляют интерпретатор работать больше. Если уровни косвенности перевешивают объём полезной работы, программа будет медленнее. Следует избегать чрезмерной абстракции, особенно в виде крошечных функций или методов (которые также часто вредят читаемости).861862Если вы достигли предела возможностей чистого Python, существуют инструменты, которые помогут пойти дальше. Например, [Cython](https://python-all.ru/3.4/faq/programming.html) может скомпилировать слегка изменённую версию кода Python в расширение C и может использоваться на многих разных платформах. Cython может использовать компиляцию (и необязательные аннотации типов), чтобы сделать ваш код значительно быстрее, чем при интерпретации. Если вы уверены в своих навыках программирования на C, вы также можете самостоятельно [*написать модуль расширения на C*](https://python-all.ru/3.4/extending/index.html#extending-index).863864> **См. также**865>866> Вики-страница, посвящённая [советам по производительности](https://python-all.ru/3.4/faq/programming.html).867868### [Как наиболее эффективно объединить много строк?](https://python-all.ru/3.4/faq/programming.html#id37)869870Объекты [`str`](https://python-all.ru/3.4/library/stdtypes.html#str) и [`bytes`](https://python-all.ru/3.4/library/functions.html#bytes) являются неизменяемыми, поэтому конкатенация многих строк неэффективна, так как каждая конкатенация создаёт новый объект. В общем случае общая стоимость выполнения квадратично зависит от общей длины строк.871872Чтобы накопить много объектов [`str`](https://python-all.ru/3.4/library/stdtypes.html#str), рекомендуется поместить их в список и в конце вызвать [`str.join()`](https://python-all.ru/3.4/library/stdtypes.html#str.join):873874```python875chunks = []876for s in my_strings:877    chunks.append(s)878result = ''.join(chunks)879```880881(другой достаточно эффективный приём – использовать [`io.StringIO`](https://python-all.ru/3.4/library/io.html#io.StringIO))882883Чтобы накопить много объектов [`bytes`](https://python-all.ru/3.4/library/functions.html#bytes), рекомендуется расширять объект [`bytearray`](https://python-all.ru/3.4/library/functions.html#bytearray) с помощью конкатенации на месте (оператор `+=`):884885```python886result = bytearray()887for b in my_bytes_objects:888    result += b889```890891## [Последовательности (кортежи/списки)](https://python-all.ru/3.4/faq/programming.html#id38)892893### [Как преобразовывать кортежи и списки друг в друга?](https://python-all.ru/3.4/faq/programming.html#id39)894895Конструктор типа `tuple(seq)` преобразует любую последовательность (на самом деле, любой итерируемый объект) в кортеж с теми же элементами в том же порядке.896897Например, `tuple([1, 2, 3])` даёт `(1, 2, 3)`, а `tuple('abc')` даёт `('a', 'b', 'c')`. Если аргумент уже является кортежем, то копия не создаётся, а возвращается тот же объект, поэтому вызов [`tuple()`](https://python-all.ru/3.4/library/stdtypes.html#tuple) дёшев, если не уверены, что объект уже кортеж.898899Конструктор типа `list(seq)` преобразует любую последовательность или итерируемый объект в список с теми же элементами в том же порядке. Например, `list((1, 2, 3))` даёт `[1, 2, 3]`, а `list('abc')` даёт `['a', 'b', 'c']`. Если аргумент уже список, то создаётся копия, как и в случае `seq[:]`.900901### [Что такое отрицательный индекс?](https://python-all.ru/3.4/faq/programming.html#id40)902903Последовательности Python индексируются положительными и отрицательными числами. Для положительных чисел 0 – это первый индекс, 1 – второй и т.д. Для отрицательных индексов -1 – это последний, -2 – предпоследний и т.д. Считайте, что `seq[-n]` эквивалентно `seq[len(seq)-n]`.904905Использование отрицательных индексов может быть очень удобным. Например, `S[:-1]` – это вся строка, кроме последнего символа, что полезно для удаления завершающего символа новой строки.906907### [Как перебрать последовательность в обратном порядке?](https://python-all.ru/3.4/faq/programming.html#id41)908909Используйте встроенную функцию [`reversed()`](https://python-all.ru/3.4/library/functions.html#reversed), которая появилась в Python 2.4:910911```python912for x in reversed(sequence):913    ... # выполнить действие с x...914```915916Это не затронет исходную последовательность, а создаст новую копию с обратным порядком для итерации.917918В Python 2.3 можно использовать расширенный синтаксис срезов:919920```python921for x in sequence[::-1]:922    ... # выполнить действие с x...923```924925### [Как удалить дубликаты из списка?](https://python-all.ru/3.4/faq/programming.html#id42)926927См. Python Cookbook, где подробно рассматриваются многие способы сделать это:928929> [http://code.activestate.com/recipes/52560/](https://python-all.ru/3.4/faq/programming.html)930931Если перестановка элементов списка не страшна, отсортируйте его, а затем просмотрите с конца, удаляя дубликаты по ходу:932933```python934if mylist:935    mylist.sort()936    last = mylist[-1]937    for i in range(len(mylist)-2, -1, -1):938        if last == mylist[i]:939            del mylist[i]940        else:941            last = mylist[i]942```943944Если все элементы списка могут использоваться как ключи множества (т.е. все они [*хешируемы*](https://python-all.ru/3.4/glossary.html#term-hashable)), это часто быстрее945946```python947mylist = list(set(mylist))948```949950Это преобразует список во множество, удаляя дубликаты, а затем обратно в список.951952### [Как создать массив в Python?](https://python-all.ru/3.4/faq/programming.html#id43)953954Используйте список:955956```python957["this", 1, "is", "an", "array"]958```959960По временно́й сложности списки эквивалентны массивам C или Pascal; основное отличие в том, что список Python может содержать объекты разных типов.961962Модуль `array` также предоставляет методы для создания массивов фиксированных типов с компактным представлением, но они медленнее индексируются, чем списки. Также обратите внимание, что расширения Numeric и другие определяют структуры, похожие на массивы, с различными характеристиками.963964Чтобы получить связные списки в стиле Lisp, можно эмулировать ячейки cons с помощью кортежей:965966```python967lisp_list = ("like",  ("this",  ("example", None) ) )968```969970Если нужна изменяемость, можно использовать списки вместо кортежей. Здесь аналог lisp car – это `lisp_list[0]`, а аналог cdr – `lisp_list[1]`. Делайте так, только если уверены, что это действительно необходимо, потому что обычно это намного медленнее, чем использование списков Python.971972### [Как создать многомерный список?](https://python-all.ru/3.4/faq/programming.html#id44)973974Вероятно, вы пытались создать многомерный массив так:975976```python977>>> A = [[None] * 2] * 3978```979980Если вывести его, выглядит правильно:981982```python983>>> A984[[None, None], [None, None], [None, None]]985```986987Но когда вы присваиваете значение, оно появляется в нескольких местах:988989```python990>>> A[0][0] = 5991>>> A992[[5, None], [5, None], [5, None]]993```994995Причина в том, что размножение списка с помощью `*` не создаёт копии, а только ссылки на существующие объекты. `*3` создаёт список из 3 ссылок на один и тот же список длины два. Изменения в одной строке отразятся во всех строках, что почти наверняка не то, что нужно.996997Рекомендуемый подход – сначала создать список нужной длины, а затем заполнить каждый элемент заново созданным списком:998999```python1000A = [None] * 31001for i in range(3):1002    A[i] = [None] * 21003```10041005Это порождает список, содержащий 3 разных списка длины два. Также можно использовать списковое включение:10061007```python1008w, h = 2, 31009A = [[None] * w for i in range(h)]1010```10111012Или можно использовать расширение, предоставляющее тип данных матрица; наиболее известно [Numeric Python](https://python-all.ru/3.4/faq/programming.html).10131014### [Как применить метод к последовательности объектов?](https://python-all.ru/3.4/faq/programming.html#id45)10151016Используйте списковое включение:10171018```python1019result = [obj.method() for obj in mylist]1020```10211022### [Почему a\_tuple\[i\] += \['item'\] вызывает исключение, хотя сложение работает?](https://python-all.ru/3.4/faq/programming.html#id46)10231024Это связано с тем, что операторы расширенного присваивания являются *операторами присваивания*, а также с различием между изменяемыми и неизменяемыми объектами в Python.10251026Это обсуждение в целом применимо, когда операторы расширенного присваивания применяются к элементам кортежа, указывающим на изменяемые объекты, но в качестве примера мы будем использовать `list` и `+=`.10271028Если написать:10291030```python1031>>> a_tuple = (1, 2)1032>>> a_tuple[0] += 11033Traceback (most recent call last):1034   ...1035TypeError: 'tuple' object does not support item assignment1036```10371038Причина исключения должна быть сразу ясна: `1` добавляется к объекту, на который указывает `a_tuple[0]` (`1`), в результате получается объект `2`, но когда мы пытаемся присвоить результат вычисления, `2`, элементу `0` кортежа, возникает ошибка, потому что мы не можем изменить то, на что указывает элемент кортежа.10391040На самом деле то, что делает этот расширенный оператор присваивания, примерно таково:10411042```python1043>>> result = a_tuple[0] + 11044>>> a_tuple[0] = result1045Traceback (most recent call last):1046  ...1047TypeError: 'tuple' object does not support item assignment1048```10491050Ошибку вызывает именно часть присваивания операции, поскольку кортеж неизменяем.10511052Если написать что-то вроде:10531054```python1055>>> a_tuple = (['foo'], 'bar')1056>>> a_tuple[0] += ['item']1057Traceback (most recent call last):1058  ...1059TypeError: 'tuple' object does not support item assignment1060```10611062Исключение несколько более неожиданно, и еще более удивительно то, что, несмотря на ошибку, append сработал:10631064```python1065>>> a_tuple[0]1066['foo', 'item']1067```10681069Чтобы понять, почему это происходит, нужно знать, что (a) если объект реализует магический метод `__iadd__`, он вызывается при выполнении расширенного присваивания `+=`, и его возвращаемое значение используется в операторе присваивания; и (b) для списков `__iadd__` эквивалентно вызову `extend` для списка и возврату списка. Вот почему мы говорим, что для списков `+=` – это "сокращение" для `list.extend`:10701071```python1072>>> a_list = []1073>>> a_list += [1]1074>>> a_list1075[1]1076```10771078Это эквивалентно:10791080```python1081>>> result = a_list.__iadd__([1])1082>>> a_list = result1083```10841085Объект, на который указывает a\_list, был изменён, и указатель на изменённый объект присваивается обратно `a_list`. Конечный результат присваивания – холостая операция, поскольку это указатель на тот же объект, на который `a_list` указывал ранее, но само присваивание всё же происходит.10861087Таким образом, в нашем примере с кортежем происходит то же самое, что и в:10881089```python1090>>> result = a_tuple[0].__iadd__(['item'])1091>>> a_tuple[0] = result1092Traceback (most recent call last):1093  ...1094TypeError: 'tuple' object does not support item assignment1095```10961097`__iadd__` выполняется успешно, и список расширяется, но даже несмотря на то, что `result` указывает на тот же объект, на который уже указывает `a_tuple[0]`, это финальное присваивание всё равно приводит к ошибке, потому что кортежи неизменяемы.10981099## [Словари](https://python-all.ru/3.4/faq/programming.html#id47)11001101### [Как сделать, чтобы словарь хранил и выводил ключи в фиксированном порядке?](https://python-all.ru/3.4/faq/programming.html#id48)11021103Используйте [`collections.OrderedDict`](https://python-all.ru/3.4/library/collections.html#collections.OrderedDict).11041105### [Я хочу выполнить сложную сортировку: можно ли сделать преобразование Шварца в Python?](https://python-all.ru/3.4/faq/programming.html#id49)11061107Этот метод, приписываемый Рэндалу Шварцу из сообщества Perl, сортирует элементы списка по метрике, которая отображает каждый элемент в его "значение сортировки". В Python просто используйте аргумент `key` для метода `sort()`:11081109```python1110Isorted = L[:]1111Isorted.sort(key=lambda s: int(s[10:15]))1112```11131114Аргумент `key` появился в Python 2.4, для более старых версий такую сортировку довольно просто выполнить с помощью списковых включений. Чтобы отсортировать список строк по их значениям в верхнем регистре:11151116```python1117tmp1 = [(x.upper(), x) for x in L]  # Преобразование Шварца1118tmp1.sort()1119Usorted = [x[1] for x in tmp1]1120```11211122Чтобы отсортировать по целочисленному значению подполя, расположенного с 10 по 15 позицию в каждой строке:11231124```python1125tmp2 = [(int(s[10:15]), s) for s in L]  # Преобразование Шварца1126tmp2.sort()1127Isorted = [x[1] for x in tmp2]1128```11291130Для версий до 3.0, Isorted также можно вычислить с помощью11311132```python1133def intfield(s):1134    return int(s[10:15])11351136def Icmp(s1, s2):1137    return cmp(intfield(s1), intfield(s2))11381139Isorted = L[:]1140Isorted.sort(Icmp)1141```11421143но поскольку этот метод вызывает `intfield()` много раз для каждого элемента L, он медленнее преобразования Шварца.11441145### [Как отсортировать один список по значениям из другого списка?](https://python-all.ru/3.4/faq/programming.html#id50)11461147Объедините их в итератор кортежей, отсортируйте полученный список, а затем извлеките нужный элемент.11481149```python1150>>> list1 = ["what", "I'm", "sorting", "by"]1151>>> list2 = ["something", "else", "to", "sort"]1152>>> pairs = zip(list1, list2)1153>>> pairs = sorted(pairs)1154>>> pairs1155[("I'm", 'else'), ('by', 'sort'), ('sorting', 'to'), ('what', 'something')]1156>>> result = [x[1] for x in pairs]1157>>> result1158['else', 'sort', 'to', 'something']1159```11601161Альтернатива для последнего шага:11621163```python1164>>> result = []1165>>> for p in pairs: result.append(p[1])1166```11671168Если такой вариант кажется вам более читаемым, возможно, вы предпочтёте его итоговому списковому включению. Однако для длинных списков он почти вдвое медленнее. Почему? Во-первых, операция `append()` требует перераспределения памяти, и хотя для этого используются некоторые уловки, чтобы избегать его каждый раз, время от времени это всё же происходит, и это обходится довольно дорого. Во-вторых, выражение «result.append» требует дополнительного поиска атрибута. В-третьих, из-за необходимости совершать все эти вызовы функций скорость снижается.11691170## [Объекты](https://python-all.ru/3.4/faq/programming.html#id51)11711172### [Что такое класс?](https://python-all.ru/3.4/faq/programming.html#id52)11731174Класс – это конкретный тип объекта, создаваемый при выполнении инструкции class. Объекты классов используются как шаблоны для создания объектов-экземпляров, которые содержат как данные (атрибуты), так и код (методы), характерные для данного типа данных.11751176Класс может быть основан на одном или нескольких других классах, называемых его базовыми классами. Он наследует атрибуты и методы своих базовых классов. Это позволяет последовательно уточнять объектную модель с помощью наследования. У вас может быть общий класс `Mailbox`, предоставляющий базовые методы доступа для почтового ящика, и подклассы, такие как `MboxMailbox`, `MaildirMailbox`, `OutlookMailbox`, которые работают с различными конкретными форматами почтовых ящиков.11771178### [Что такое метод?](https://python-all.ru/3.4/faq/programming.html#id53)11791180Метод – это функция некоторого объекта `x`, которую обычно вызывают как `x.name(аргументы...)`. Методы определяются как функции внутри определения класса:11811182```python1183class C:1184    def meth (self, arg):1185        return arg * 2 + self.attribute1186```11871188### [Что такое self?](https://python-all.ru/3.4/faq/programming.html#id54)11891190Self – это всего лишь общепринятое имя для первого аргумента метода. Метод, определённый как `meth(self, a, b, c)`, следует вызывать как `x.meth(a, b, c)` для некоторого экземпляра `x` класса, в котором находится определение; вызываемый метод будет считать, что его вызвали как `meth(x, a, b, c)`.11911192См. также [*Почему self должно явно использоваться в определениях и вызовах методов?*](https://python-all.ru/3.4/faq/design.html#why-self).11931194### [Как проверить, является ли объект экземпляром данного класса или его подкласса?](https://python-all.ru/3.4/faq/programming.html#id55)11951196Используйте встроенную функцию `isinstance(obj, cls)`. Можно проверить, является ли объект экземпляром любого из нескольких классов, передав кортеж вместо одного класса, например `isinstance(obj, (class1, class2, ...))`, а также можно проверить, является ли объект одним из встроенных типов Python, например `isinstance(obj, str)` или `isinstance(obj, (int, float, complex))`.11971198Обратите внимание: в большинстве программ [`isinstance()`](https://python-all.ru/3.4/library/functions.html#isinstance) для пользовательских классов используется нечасто. Если вы сами разрабатываете классы, более правильным объектно-ориентированным стилем будет определять в классах методы, инкапсулирующие определённое поведение, вместо проверки класса объекта и выполнения разных действий в зависимости от того, к какому классу он принадлежит. Например, если у вас есть функция, которая делает что-то:11991200```python1201def search(obj):1202    if isinstance(obj, Mailbox):1203        # ... код для поиска в почтовом ящике1204    elif isinstance(obj, Document):1205        # ... код для поиска в документе1206    elif ...1207```12081209Более правильный подход – определить метод `search()` во всех классах и просто вызывать его:12101211```python1212class Mailbox:1213    def search(self):1214        # ... код для поиска в почтовом ящике12151216class Document:1217    def search(self):1218        # ... код для поиска в документе12191220obj.search()1221```12221223### [Что такое делегирование?](https://python-all.ru/3.4/faq/programming.html#id56)12241225Делегирование – это объектно-ориентированный приём (также называемый шаблоном проектирования). Допустим, у вас есть объект `x`, и вы хотите изменить поведение только одного из его методов. Можно создать новый класс, который предоставляет новую реализацию интересующего вас метода, а все остальные методы делегирует соответствующим методам объекта `x`.12261227Программисты на Python могут легко реализовать делегирование. Например, следующий класс реализует класс, который ведёт себя как файл, но преобразует все записываемые данные в верхний регистр:12281229```python1230class UpperOut:12311232    def __init__(self, outfile):1233        self._outfile = outfile12341235    def write(self, s):1236        self._outfile.write(s.upper())12371238    def __getattr__(self, name):1239        return getattr(self._outfile, name)1240```12411242Здесь класс `UpperOut` переопределяет метод `write()`, чтобы преобразовывать строку аргумента в верхний регистр перед вызовом базового метода `self.__outfile.write()`. Все остальные методы делегируются базовому объекту `self.__outfile`. Делегирование осуществляется через метод `__getattr__`; обратитесь к [*ссылке на язык*](https://python-all.ru/3.4/reference/datamodel.html#attribute-access) для получения дополнительной информации об управлении доступом к атрибутам.12431244Обратите внимание: в более общих случаях делегирование может усложняться. Когда атрибуты необходимо не только получать, но и устанавливать, класс должен также определить метод [`__setattr__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__setattr__), и делать это нужно аккуратно. Базовая реализация [`__setattr__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__setattr__) примерно эквивалентна следующему:12451246```python1247class X:1248    ...1249    def __setattr__(self, name, value):1250        self.__dict__[name] = value1251    ...1252```12531254Большинство реализаций [`__setattr__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__setattr__) должны изменять `self.__dict__` для хранения локального состояния self, чтобы не вызывать бесконечную рекурсию.12551256### [Как вызвать метод, определённый в базовом классе, из производного класса, который его переопределяет?](https://python-all.ru/3.4/faq/programming.html#id57)12571258Используйте встроенную функцию [`super()`](https://python-all.ru/3.4/library/functions.html#super):12591260```python1261class Derived(Base):1262    def meth (self):1263        super(Derived, self).meth()1264```12651266Для версий до 3.0 вы могли использовать классические классы. Для определения класса вида `class Derived(Base): ...` можно вызвать метод `meth()`, определённый в `Base` (или одном из базовых классов `Base`), как `Base.meth(self, аргументы...)`. Здесь `Base.meth` – это несвязанный метод, поэтому нужно передать аргумент `self`.12671268### [Как организовать код, чтобы было проще изменить базовый класс?](https://python-all.ru/3.4/faq/programming.html#id58)12691270Можно определить псевдоним для базового класса, присвоить ему реальный базовый класс до определения вашего класса и использовать псевдоним во всём классе. Тогда всё, что нужно изменить – это значение, присвоенное псевдониму. Кстати, этот трюк также удобен, если вы хотите динамически (например, в зависимости от доступности ресурсов) выбирать, какой базовый класс использовать. Пример:12711272```python1273BaseAlias = <real base class>12741275class Derived(BaseAlias):1276    def meth(self):1277        BaseAlias.meth(self)1278        ...1279```12801281### [Как создать статические данные класса и статические методы класса?](https://python-all.ru/3.4/faq/programming.html#id59)12821283В Python поддерживаются как статические данные, так и статические методы (в смысле C++ или Java).12841285Для статических данных просто определите атрибут класса. Чтобы присвоить атрибуту новое значение, необходимо явно указать имя класса в присваивании:12861287```python1288class C:1289    count = 0   # количество вызовов C.__init__12901291    def __init__(self):1292        C.count = C.count + 112931294    def getcount(self):1295        return C.count  # или вернуть self.count1296```12971298`c.count` также ссылается на `C.count` для любого `c`, для которого выполняется `isinstance(c, C)`, если только это не переопределено самим объектом `c` или каким-либо классом на пути поиска от `c.__class__` обратно к `C`.12991300Предупреждение: внутри метода C присваивание вида `self.count = 42` создаёт новый, не связанный экземпляр с именем «count» в собственном словаре `self`. Повторное связывание статического имени данных класса всегда должно указывать сам класс, независимо от того, находится ли оно внутри метода или нет:13011302```python1303C.count = 3141304```13051306Статические методы возможны:13071308```python1309class C:1310    @staticmethod1311    def static(arg1, arg2, arg3):1312        # Нет параметра 'self'!1313        ...1314```13151316Однако гораздо более прямолинейный способ получить эффект статического метода – это простая функция уровня модуля:13171318```python1319def getcount():1320    return C.count1321```13221323Если код организован так, что на каждый модуль определён один класс (или тесно связанная иерархия классов), это обеспечивает нужную инкапсуляцию.13241325### [Как перегрузить конструкторы (или методы) в Python?](https://python-all.ru/3.4/faq/programming.html#id60)13261327Этот ответ на самом деле применим ко всем методам, но вопрос обычно возникает в первую очередь в контексте конструкторов.13281329В C++ вы бы написали13301331```c1332class C {1333    C() { cout << "No arguments\n"; }1334    C(int i) { cout << "Argument is " << i << "\n"; }1335}1336```13371338В Python нужно написать один конструктор, который обрабатывает все случаи с помощью аргументов по умолчанию. Например:13391340```python1341class C:1342    def __init__(self, i=None):1343        if i is None:1344            print("No arguments")1345        else:1346            print("Argument is", i)1347```13481349Это не полностью эквивалентно, но на практике достаточно близко.13501351Можно также попробовать список аргументов переменной длины, например13521353```python1354def __init__(self, *args):1355    ...1356```13571358Тот же подход работает для всех определений методов.13591360### [Я пытаюсь использовать \_\_spam и получаю ошибку про \_SomeClassName\_\_spam.](https://python-all.ru/3.4/faq/programming.html#id61)13611362Имена переменных с двойным подчёркиванием в начале подвергаются «искажению», что даёт простой, но эффективный способ определения частных переменных класса. Любой идентификатор вида `__spam` (не менее двух ведущих подчёркиваний, не более одного завершающего) текстуально заменяется на `_classname__spam`, где `classname` – это имя текущего класса с удалёнными ведущими подчёркиваниями.13631364Это не гарантирует приватности: внешний пользователь всё равно может намеренно получить доступ к атрибуту «\_classname\_\_spam», а частные значения видны в `__dict__` объекта. Многие программисты Python вообще не утруждают себя использованием частных имён переменных.13651366### [Мой класс определяет \_\_del\_\_, но он не вызывается, когда я удаляю объект.](https://python-all.ru/3.4/faq/programming.html#id62)13671368Для этого есть несколько возможных причин.13691370Оператор [https://python-all.ru/3.4/reference/datamodel.html#object.__del__](https://python-all.ru/3.4/reference/datamodel.html#object.__del__)del не обязательно вызывает `__del__()` – он просто уменьшает счётчик ссылок объекта, и если тот достигает нуля, вызывается [`__del__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__del__).13711372Если ваши структуры данных содержат циклические ссылки (например, дерево, где каждый потомок имеет ссылку на родителя, а каждый родитель – список потомков), счётчики ссылок никогда не обнулятся. Время от времени Python запускает алгоритм для обнаружения таких циклов, но сборщик мусора может запуститься спустя некоторое время после исчезновения последней ссылки на вашу структуру данных, поэтому ваш метод [`__del__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__del__) может быть вызван в неудобный и случайный момент. Это неудобно, если вы пытаетесь воспроизвести проблему. Хуже того, порядок, в котором выполняются методы [`__del__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__del__) объектов, произволен. Вы можете запустить [`gc.collect()`](https://python-all.ru/3.4/library/gc.html#gc.collect), чтобы принудительно выполнить сборку, но существуют *патологические* случаи, когда объекты никогда не будут собраны.13731374Несмотря на сборщик циклов, всё же стоит определять явный метод `close()` для объектов, который следует вызывать, когда объект больше не нужен. Метод `close()` может затем удалять атрибуты, ссылающиеся на подобъекты. Не вызывайте [`__del__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__del__) напрямую – [`__del__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__del__) должен вызывать `close()`, а `close()` должен гарантировать, что его можно вызвать для одного и того же объекта несколько раз.13751376Ещё один способ избежать циклических ссылок – использовать модуль [`weakref`](https://python-all.ru/3.4/library/weakref.html#module-weakref), который позволяет указывать на объекты без увеличения их счётчика ссылок. Например, в древовидных структурах данных для ссылок на родителя и соседей (если они нужны) следует использовать слабые ссылки.13771378Наконец, если ваш метод [`__del__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__del__) вызывает исключение, в [`sys.stderr`](https://python-all.ru/3.4/library/sys.html#sys.stderr) выводится предупреждение.13791380### [Как получить список всех экземпляров данного класса?](https://python-all.ru/3.4/faq/programming.html#id63)13811382Python не отслеживает все экземпляры класса (или встроенного типа). Можно запрограммировать конструктор класса так, чтобы он отслеживал все экземпляры, сохраняя список слабых ссылок на каждый экземпляр.13831384### [Почему результат `id()` кажется неуникальным?](https://python-all.ru/3.4/faq/programming.html#id64)13851386Встроенная функция [`id()`](https://python-all.ru/3.4/library/functions.html#id) возвращает целое число, которое гарантированно будет уникальным на время жизни объекта. Поскольку в CPython это адрес памяти объекта, часто бывает, что после удаления объекта из памяти следующий только что созданный объект выделяется в той же позиции памяти. Это иллюстрируется следующим примером:13871388```python1389>>> id(1000)1390139012721391>>> id(2000)1392139012721393```13941395Два идентификатора принадлежат разным целочисленным объектам, которые создаются до вызова `id()` и сразу после него удаляются. Чтобы убедиться, что объекты, чьи идентификаторы вы хотите проверить, всё ещё существуют, создайте другую ссылку на объект:13961397```python1398>>> a = 1000; b = 20001399>>> id(a)1400139012721401>>> id(b)1402138912961403```14041405## [Модули](https://python-all.ru/3.4/faq/programming.html#id65)14061407### [Как создать .pyc-файл?](https://python-all.ru/3.4/faq/programming.html#id66)14081409Когда модуль импортируется впервые (или когда исходный файл изменился с момента создания текущего скомпилированного файла), в подкаталоге `__pycache__` каталога, содержащего файл `.py`, должен быть создан файл `.pyc` с скомпилированным кодом. Имя файла `.pyc` будет начинаться с того же имени, что и файл `.py`, и заканчиваться на `.pyc`, со средним компонентом, зависящим от конкретного двоичного файла `python`, который его создал. (Подробнее см. [**PEP 3147**](https://python-all.ru/3.4/faq/programming.html).)14101411Одна из причин, по которой файл `.pyc` может не создаваться, – проблема с правами доступа к каталогу, содержащему исходный файл, из-за чего не может быть создан подкаталог `__pycache__`. Это может произойти, например, если вы разрабатываете как один пользователь, а запускаете как другой, например, при тестировании с веб-сервером.14121413Если не установлена переменная окружения [`PYTHONDONTWRITEBYTECODE`](https://python-all.ru/3.4/using/cmdline.html#envvar-PYTHONDONTWRITEBYTECODE), создание файла .pyc происходит автоматически при импорте модуля, если у Python есть возможность (права доступа, свободное место и т.д.) создать подкаталог `__pycache__` и записать в него скомпилированный модуль.14141415Запуск Python для сценария верхнего уровня не считается импортом, и файл `.pyc` создан не будет. Например, если у вас есть модуль верхнего уровня `foo.py`, который импортирует другой модуль `xyz.py`, то при запуске `foo` (введя команду оболочки `python foo.py`) файл `.pyc` будет создан для `xyz`, поскольку `xyz` импортируется, но файл `.pyc` не будет создан для `foo`, так как `foo.py` не импортируется.14161417Если вам нужно создать файл `.pyc` для `foo` – то есть создать файл `.pyc` для модуля, который не импортируется, – это можно сделать с помощью модулей [`py_compile`](https://python-all.ru/3.4/library/py_compile.html#module-py_compile) и [`compileall`](https://python-all.ru/3.4/library/compileall.html#module-compileall).14181419Модуль [`py_compile`](https://python-all.ru/3.4/library/py_compile.html#module-py_compile) может вручную компилировать любой модуль. Один из способов – интерактивно использовать функцию `compile()` из этого модуля:14201421```python1422>>> import py_compile1423>>> py_compile.compile('foo.py')                 1424```14251426Это запишет `.pyc` в подкаталог `__pycache__` в том же месте, что и `foo.py` (или вы можете переопределить это с помощью необязательного параметра `cfile`).14271428Вы также можете автоматически скомпилировать все файлы в каталоге или каталогах, используя модуль [`compileall`](https://python-all.ru/3.4/library/compileall.html#module-compileall). Это можно сделать из командной строки, запустив `compileall.py` и указав путь к каталогу, содержащему файлы Python для компиляции:14291430```python1431python -m compileall .1432```14331434### [Как узнать имя текущего модуля?](https://python-all.ru/3.4/faq/programming.html#id67)14351436Модуль может узнать своё собственное имя, обратившись к предопределённой глобальной переменной `__name__`. Если она равна `'__main__'`, программа выполняется как сценарий. Многие модули, которые обычно используются путём импорта, также предоставляют интерфейс командной строки или самопроверку и выполняют этот код только после проверки `__name__`:14371438```python1439def main():1440    print('Running test...')1441    ...14421443if __name__ == '__main__':1444    main()1445```14461447### [Как сделать модули, которые импортируют друг друга?](https://python-all.ru/3.4/faq/programming.html#id68)14481449Предположим, у вас есть следующие модули:14501451foo.py:14521453```python1454from bar import bar_var1455foo_var = 11456```14571458bar.py:14591460```python1461from foo import foo_var1462bar_var = 21463```14641465Проблема в том, что интерпретатор выполнит следующие шаги:14661467- main импортирует foo1468- Создаются пустые глобальные переменные для foo1469- foo компилируется и начинает выполняться1470- foo импортирует bar1471- Создаются пустые глобальные переменные для bar1472- bar компилируется и начинает выполняться1473- bar импортирует foo (это пустая операция, так как модуль с именем foo уже существует)1474- bar.foo\_var = foo.foo\_var14751476Последний шаг завершается ошибкой, потому что Python ещё не закончил интерпретацию `foo`, и глобальный словарь символов для `foo` всё ещё пуст.14771478То же самое происходит при использовании `import foo` и последующей попытке обратиться к `foo.foo_var` в глобальном коде.14791480Существует (как минимум) три возможных обходных решения этой проблемы.14811482Гвидо ван Россум рекомендует избегать всех случаев использования `from <module> import ...` и размещать весь код внутри функций. Инициализации глобальных переменных и переменных класса должны использовать только константы или встроенные функции. Это означает, что всё из импортированного модуля указывается как `<module>.<name>`.14831484Джим Роскинд предлагает выполнять шаги в следующем порядке в каждом модуле:14851486- экспорт (глобальные переменные, функции и классы, которым не нужны импортированные базовые классы)1487- Операторы `import`1488- активный код (включая глобальные переменные, инициализируемые из импортированных значений).14891490ван Россуму такой подход не очень нравится, потому что импорты оказываются в странном месте, но это работает.14911492Маттиас Урлихс рекомендует перестроить код так, чтобы рекурсивный импорт вообще не требовался.14931494Эти решения не являются взаимоисключающими.14951496### [\_\_import\_\_(‘x.y.z’) возвращает \<module ‘x’\>; как получить z?](https://python-all.ru/3.4/faq/programming.html#id69)14971498Рассмотрите возможность использования удобной функции [`import_module()`](https://python-all.ru/3.4/library/importlib.html#importlib.import_module) из [`importlib`](https://python-all.ru/3.4/library/importlib.html#module-importlib) вместо:14991500```python1501z = importlib.import_module('x.y.z')1502```15031504### [Когда я редактирую импортированный модуль и повторно импортирую его, изменения не отображаются. Почему это происходит?](https://python-all.ru/3.4/faq/programming.html#id70)15051506Из соображений эффективности и согласованности Python читает файл модуля только при первом импорте модуля. Если бы это было не так, в программе, состоящей из многих модулей, каждый из которых импортирует один и тот же базовый модуль, этот базовый модуль разбирался бы и переразбирался много раз. Чтобы принудительно перечитать изменённый модуль, сделайте следующее:15071508```python1509import importlib1510import modname1511importlib.reload(modname)1512```15131514Предупреждение: этот метод не является абсолютно надёжным. В частности, модули, содержащие операторы типа15151516```python1517from modname import some_objects1518```15191520будут продолжать работать со старой версией импортированных объектов. Если модуль содержит определения классов, существующие экземпляры классов *не* будут обновлены для использования нового определения класса. Это может привести к следующему парадоксальному поведению:15211522```python1523>>> import importlib1524>>> import cls1525>>> c = cls.C()                # Создать экземпляр C1526>>> importlib.reload(cls)1527<module 'cls' from 'cls.py'>1528>>> isinstance(c, cls.C)       # isinstance ложно?!?1529False1530```15311532Суть проблемы становится ясна, если вывести «идентичность» объектов классов:15331534```python1535>>> hex(id(c.__class__))1536'0x7352a0'1537>>> hex(id(cls.C))1538'0x4198d0'1539```1540