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

programming.md

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

1> **Источник:** https://python-all.ru/2.6/faq/programming.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# [ЧЗВ по программированию](https://python-all.ru/2.6/faq/programming.html#id1)89Содержание1011- [Вопросы по программированию](https://python-all.ru/2.6/faq/programming.html#programming-faq)1213  - [Общие вопросы](https://python-all.ru/2.6/faq/programming.html#general-questions)1415    - [Существует ли отладчик на уровне исходного кода с точками останова, пошаговым выполнением и т. д.?](https://python-all.ru/2.6/faq/programming.html#is-there-a-source-code-level-debugger-with-breakpoints-single-stepping-etc)16    - [Существует ли инструмент для поиска ошибок или выполнения статического анализа?](https://python-all.ru/2.6/faq/programming.html#is-there-a-tool-to-help-find-bugs-or-perform-static-analysis)17    - [Как создать автономный исполняемый файл из скрипта Python?](https://python-all.ru/2.6/faq/programming.html#how-can-i-create-a-stand-alone-binary-from-a-python-script)18    - [Существуют ли стандарты кодирования или руководство по стилю для программ на Python?](https://python-all.ru/2.6/faq/programming.html#are-there-coding-standards-or-a-style-guide-for-python-programs)19    - [Моя программа слишком медленная. Как её ускорить?](https://python-all.ru/2.6/faq/programming.html#my-program-is-too-slow-how-do-i-speed-it-up)20  - [Ядро языка](https://python-all.ru/2.6/faq/programming.html#core-language)2122    - [Почему возникает UnboundLocalError, если переменная имеет значение?](https://python-all.ru/2.6/faq/programming.html#why-am-i-getting-an-unboundlocalerror-when-the-variable-has-a-value)23    - [Каковы правила для локальных и глобальных переменных в Python?](https://python-all.ru/2.6/faq/programming.html#what-are-the-rules-for-local-and-global-variables-in-python)24    - [Как разделять глобальные переменные между модулями?](https://python-all.ru/2.6/faq/programming.html#how-do-i-share-global-variables-across-modules)25    - [Каковы «лучшие практики» использования import в модуле?](https://python-all.ru/2.6/faq/programming.html#what-are-the-best-practices-for-using-import-in-a-module)26    - [Как передать необязательные или именованные параметры из одной функции в другую?](https://python-all.ru/2.6/faq/programming.html#how-can-i-pass-optional-or-keyword-parameters-from-one-function-to-another)27    - [Как написать функцию с выходными параметрами (передача по ссылке)?](https://python-all.ru/2.6/faq/programming.html#how-do-i-write-a-function-with-output-parameters-call-by-reference)28    - [Как создать функцию высшего порядка в Python?](https://python-all.ru/2.6/faq/programming.html#how-do-you-make-a-higher-order-function-in-python)29    - [Как скопировать объект в Python?](https://python-all.ru/2.6/faq/programming.html#how-do-i-copy-an-object-in-python)30    - [Как найти методы или атрибуты объекта?](https://python-all.ru/2.6/faq/programming.html#how-can-i-find-the-methods-or-attributes-of-an-object)31    - [Как моему коду узнать имя объекта?](https://python-all.ru/2.6/faq/programming.html#how-can-my-code-discover-the-name-of-an-object)32    - [Что не так с приоритетом оператора запятой?](https://python-all.ru/2.6/faq/programming.html#what-s-up-with-the-comma-operator-s-precedence)33    - [Существует ли эквивалент тернарного оператора «?:» из C?](https://python-all.ru/2.6/faq/programming.html#is-there-an-equivalent-of-c-s-ternary-operator)34    - [Можно ли писать запутанные однострочники на Python?](https://python-all.ru/2.6/faq/programming.html#is-it-possible-to-write-obfuscated-one-liners-in-python)35  - [Числа и строки](https://python-all.ru/2.6/faq/programming.html#numbers-and-strings)3637    - [Как указать шестнадцатеричные и восьмеричные целые числа?](https://python-all.ru/2.6/faq/programming.html#how-do-i-specify-hexadecimal-and-octal-integers)38    - [Почему -22 // 10 возвращает -3?](https://python-all.ru/2.6/faq/programming.html#why-does-22-10-return-3)39    - [Как преобразовать строку в число?](https://python-all.ru/2.6/faq/programming.html#how-do-i-convert-a-string-to-a-number)40    - [Как преобразовать число в строку?](https://python-all.ru/2.6/faq/programming.html#how-do-i-convert-a-number-to-a-string)41    - [Как изменить строку на месте?](https://python-all.ru/2.6/faq/programming.html#how-do-i-modify-a-string-in-place)42    - [Как с помощью строк вызывать функции и методы?](https://python-all.ru/2.6/faq/programming.html#how-do-i-use-strings-to-call-functions-methods)43    - [Существует ли аналог функции chomp() из Perl для удаления завершающих символов новой строки из строк?](https://python-all.ru/2.6/faq/programming.html#is-there-an-equivalent-to-perl-s-chomp-for-removing-trailing-newlines-from-strings)44    - [Существует ли аналог функций scanf() или sscanf()?](https://python-all.ru/2.6/faq/programming.html#is-there-a-scanf-or-sscanf-equivalent)45    - [Что означает ошибка «UnicodeError: ASCII \[decoding,encoding\] error: ordinal not in range(128)»?](https://python-all.ru/2.6/faq/programming.html#what-does-unicodeerror-ascii-decoding-encoding-error-ordinal-not-in-range-128-mean)46  - [Последовательности (кортежи/списки)](https://python-all.ru/2.6/faq/programming.html#sequences-tuples-lists)4748    - [Как преобразовывать кортежи в списки и обратно?](https://python-all.ru/2.6/faq/programming.html#how-do-i-convert-between-tuples-and-lists)49    - [Что такое отрицательный индекс?](https://python-all.ru/2.6/faq/programming.html#what-s-a-negative-index)50    - [Как перебрать последовательность в обратном порядке?](https://python-all.ru/2.6/faq/programming.html#how-do-i-iterate-over-a-sequence-in-reverse-order)51    - [Как удалить дубликаты из списка?](https://python-all.ru/2.6/faq/programming.html#how-do-you-remove-duplicates-from-a-list)52    - [Как создать массив в Python?](https://python-all.ru/2.6/faq/programming.html#how-do-you-make-an-array-in-python)53    - [Как создать многомерный список?](https://python-all.ru/2.6/faq/programming.html#how-do-i-create-a-multidimensional-list)54    - [Как применить метод к последовательности объектов?](https://python-all.ru/2.6/faq/programming.html#how-do-i-apply-a-method-to-a-sequence-of-objects)55  - [Словари](https://python-all.ru/2.6/faq/programming.html#dictionaries)5657    - [Как сделать так, чтобы ключи словаря отображались в постоянном порядке?](https://python-all.ru/2.6/faq/programming.html#how-can-i-get-a-dictionary-to-display-its-keys-in-a-consistent-order)58    - [Я хочу выполнить сложную сортировку: можно ли в Python реализовать преобразование Шварца?](https://python-all.ru/2.6/faq/programming.html#i-want-to-do-a-complicated-sort-can-you-do-a-schwartzian-transform-in-python)59    - [Как отсортировать один список по значениям из другого списка?](https://python-all.ru/2.6/faq/programming.html#how-can-i-sort-one-list-by-values-from-another-list)60  - [Объекты](https://python-all.ru/2.6/faq/programming.html#objects)6162    - [Что такое класс?](https://python-all.ru/2.6/faq/programming.html#what-is-a-class)63    - [Что такое метод?](https://python-all.ru/2.6/faq/programming.html#what-is-a-method)64    - [Что такое self?](https://python-all.ru/2.6/faq/programming.html#what-is-self)65    - [Как проверить, является ли объект экземпляром данного класса или его подкласса?](https://python-all.ru/2.6/faq/programming.html#how-do-i-check-if-an-object-is-an-instance-of-a-given-class-or-of-a-subclass-of-it)66    - [Что такое делегирование?](https://python-all.ru/2.6/faq/programming.html#what-is-delegation)67    - [Как вызвать метод, определённый в базовом классе, из производного класса, который его переопределяет?](https://python-all.ru/2.6/faq/programming.html#how-do-i-call-a-method-defined-in-a-base-class-from-a-derived-class-that-overrides-it)68    - [Как организовать код, чтобы было проще изменить базовый класс?](https://python-all.ru/2.6/faq/programming.html#how-can-i-organize-my-code-to-make-it-easier-to-change-the-base-class)69    - [Как создать статические данные класса и статические методы класса?](https://python-all.ru/2.6/faq/programming.html#how-do-i-create-static-class-data-and-static-class-methods)70    - [Как перегрузить конструкторы (или методы) в Python?](https://python-all.ru/2.6/faq/programming.html#how-can-i-overload-constructors-or-methods-in-python)71    - [Я пытаюсь использовать \_\_spam и получаю ошибку о \_SomeClassName\_\_spam.](https://python-all.ru/2.6/faq/programming.html#i-try-to-use-spam-and-i-get-an-error-about-someclassname-spam)72    - [Мой класс определяет \_\_del\_\_, но он не вызывается при удалении объекта.](https://python-all.ru/2.6/faq/programming.html#my-class-defines-del-but-it-is-not-called-when-i-delete-the-object)73    - [Как получить список всех экземпляров данного класса?](https://python-all.ru/2.6/faq/programming.html#how-do-i-get-a-list-of-all-instances-of-a-given-class)74  - [Модули](https://python-all.ru/2.6/faq/programming.html#modules)7576    - [Как создать .pyc-файл?](https://python-all.ru/2.6/faq/programming.html#how-do-i-create-a-pyc-file)77    - [Как узнать имя текущего модуля?](https://python-all.ru/2.6/faq/programming.html#how-do-i-find-the-current-module-name)78    - [Как сделать так, чтобы модули импортировали друг друга?](https://python-all.ru/2.6/faq/programming.html#how-can-i-have-modules-that-mutually-import-each-other)79    - [\_\_import\_\_(‘x.y.z’) возвращает \<module ‘x’\>; как получить z?](https://python-all.ru/2.6/faq/programming.html#import-x-y-z-returns-module-x-how-do-i-get-z)80    - [При редактировании импортированного модуля и его повторном импорте изменения не отображаются. Почему это происходит?](https://python-all.ru/2.6/faq/programming.html#when-i-edit-an-imported-module-and-reimport-it-the-changes-don-t-show-up-why-does-this-happen)8182## [Общие вопросы](https://python-all.ru/2.6/faq/programming.html#id2)8384### [Существует ли отладчик на уровне исходного кода с точками останова, пошаговым выполнением и т. д.?](https://python-all.ru/2.6/faq/programming.html#id3)8586Да.8788The 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/2.6/library/pdb.html#module-pdb). You can also write your own debugger by using the code for pdb as an example.8990Интерактивная среда разработки IDLE, входящая в стандартный дистрибутив Python (обычно доступна как Tools/scripts/idle), включает графический отладчик. Документация по отладчику IDLE находится по адресу [http://www.python.org/idle/doc/idle2.html#Debugger](https://python-all.ru/2.6/faq/programming.html).9192PythonWin – это IDE для Python, включающая графический отладчик на основе pdb. Отладчик PythonWin раскрашивает точки останова и обладает рядом полезных возможностей, таких как отладка программ, не являющихся программами PythonWin. PythonWin доступен как часть проекта [Python for Windows Extensions](https://python-all.ru/2.6/faq/programming.html), а также в составе дистрибутива ActivePython (см. [http://www.activestate.com/Products/ActivePython/index.html](https://python-all.ru/2.6/faq/programming.html)).9394[Boa Constructor](https://python-all.ru/2.6/faq/programming.html) – это среда разработки и конструктор графического интерфейса на основе wxWidgets. Он предоставляет визуальное создание и редактирование фреймов, инспектор объектов, различные представления исходного кода, включая обозреватели объектов, иерархии наследования, HTML-документацию, сгенерированную из строк документации, расширенный отладчик, встроенную справку и поддержку Zope.9596[Eric](https://python-all.ru/2.6/faq/programming.html) – это IDE, построенная на PyQt и компоненте редактирования Scintilla.9798Pydb – это версия стандартного отладчика Python pdb, модифицированная для использования с DDD (Data Display Debugger) – популярным графическим интерфейсом отладчика. Pydb можно найти по адресу [http://bashdb.sourceforge.net/pydb/](https://python-all.ru/2.6/faq/programming.html), а DDD – по адресу [http://www.gnu.org/software/ddd](https://python-all.ru/2.6/faq/programming.html).99100Существует ряд коммерческих IDE для Python, включающих графические отладчики. Среди них:101102- Wing IDE ([http://wingware.com/](https://python-all.ru/2.6/faq/programming.html))103- Komodo IDE ([http://www.activestate.com/Products/Komodo](https://python-all.ru/2.6/faq/programming.html))104105### [Существует ли инструмент для поиска ошибок или выполнения статического анализа?](https://python-all.ru/2.6/faq/programming.html#id4)106107Да.108109PyChecker – это инструмент статического анализа, который находит ошибки в исходном коде Python и предупреждает о сложности и стиле кода. PyChecker можно получить по адресу [http://pychecker.sf.net](https://python-all.ru/2.6/faq/programming.html).110111[Pylint](https://python-all.ru/2.6/faq/programming.html) – ещё один инструмент, который проверяет, соответствует ли модуль стандарту кодирования, а также позволяет писать плагины для добавления собственных функций. В дополнение к поиску ошибок, выполняемому PyChecker, Pylint предлагает несколько дополнительных возможностей, таких как проверка длины строки, соответствие имён переменных вашему стандарту кодирования, полная реализация объявленных интерфейсов и другие. На странице [http://www.logilab.org/card/pylint\_manual](https://python-all.ru/2.6/faq/programming.html) приведён полный список возможностей Pylint.112113### [Как создать автономный исполняемый файл из скрипта Python?](https://python-all.ru/2.6/faq/programming.html#id5)114115Вам не нужно уметь компилировать Python в C, если ваша цель – создать автономную программу, которую пользователи могут скачать и запустить без предварительной установки дистрибутива Python. Существует ряд инструментов, которые определяют набор модулей, необходимых программе, и связывают эти модули вместе с бинарным файлом Python, создавая единый исполняемый файл.116117Один из способов – использовать инструмент freeze, который входит в исходный код Python как `Tools/freeze`. Он преобразует байт-код Python в массивы C; с помощью компилятора C вы можете встроить все свои модули в новую программу, которая затем связывается со стандартными модулями Python.118119Он работает, рекурсивно сканируя ваш исходный код на наличие операторов import (в обеих формах) и ищет модули в стандартном пути Python, а также в каталоге исходного кода (для встроенных модулей). Затем он превращает байт-код модулей, написанных на Python, в код C (инициализаторы массивов, которые можно превратить в объекты кода с помощью модуля marshal) и создает специальный конфигурационный файл, содержащий только те встроенные модули, которые действительно используются в программе. После этого он компилирует сгенерированный код C и компонует его с остальной частью интерпретатора Python, формируя самодостаточный бинарный файл, который ведет себя точно так же, как ваш скрипт.120121Очевидно, freeze требует компилятор C. Существует несколько других утилит, которые не требуют. Одна из них – py2exe Томаса Хеллера (только для Windows) по адресу122123> [http://www.py2exe.org/](https://python-all.ru/2.6/faq/programming.html)124125Ещё один – [SQFREEZE](https://python-all.ru/2.6/faq/programming.html) Кристиана Тисмера, который добавляет байт-код к специально подготовленному интерпретатору Python, способному найти байт-код в исполняемом файле.126127Другие инструменты включают [Squeeze](https://python-all.ru/2.6/faq/programming.html) Фредрика Лунда и [cx\_Freeze](https://python-all.ru/2.6/faq/programming.html) Энтони Туйнинги.128129### [Существуют ли стандарты кодирования или руководство по стилю для программ на Python?](https://python-all.ru/2.6/faq/programming.html#id6)130131Да. Требуемый стиль оформления кода для модулей стандартной библиотеки описан в документе [**PEP 8**](https://python-all.ru/2.6/faq/programming.html).132133### [Моя программа слишком медленная. Как её ускорить?](https://python-all.ru/2.6/faq/programming.html#id7)134135В целом, ответить непросто. Существует множество приёмов для ускорения Python-кода; переписывание частей на C стоит рассматривать лишь как крайнюю меру.136137В некоторых случаях Python можно автоматически преобразовать в C или ассемблер x86, а значит, для повышения быстродействия не требуется изменять код.138139[Pyrex](https://python-all.ru/2.6/faq/programming.html) позволяет компилировать немного изменённую версию кода Python в расширение C и работает на множестве различных платформ.140141[Psyco](https://python-all.ru/2.6/faq/programming.html) – это JIT-компилятор, транслирующий код Python в ассемблер x86. При возможности использования Psyco может существенно ускорить выполнение критических функций.142143В оставшейся части ответа будут рассмотрены различные приёмы для извлечения дополнительной скорости из кода Python. *Никогда* не следует применять какие-либо оптимизации, если не известно, что они нужны, и только после того, как профилирование показало, что конкретная функция является наиболее часто выполняемым узким местом в коде. Оптимизации почти всегда снижают понятность кода, и не стоит платить цену снижения ясности (увеличение времени разработки, большая вероятность ошибок), если только результирующий выигрыш в производительности того не стоит.144145На вики есть страница, посвящённая [советам по производительности](https://python-all.ru/2.6/faq/programming.html).146147Гвидо ван Россум опубликовал историю, связанную с оптимизацией, на [http://www.python.org/doc/essays/list2str.html](https://python-all.ru/2.6/faq/programming.html).148149Стоит заметить, что вызовы функций и (особенно) методов довольно дороги; если спроектирован чисто объектно-ориентированный интерфейс с множеством крошечных функций, которые не делают ничего, кроме получения или установки переменной экземпляра или вызова другого метода, возможно, стоит рассмотреть более прямой способ, например, прямой доступ к переменным экземпляра. Также стоит обратить внимание на стандартный модуль [`profile`](https://python-all.ru/2.6/library/profile.html#module-profile), который позволяет выяснить, где программа проводит большую часть времени (если проявить терпение – само профилирование может замедлить программу на порядок).150151Следует помнить, что многие стандартные эвристики оптимизации, известные из другого опыта программирования, применимы и к Python. Например, отправка вывода на устройства вывода более крупными порциями может быть быстрее, чем мелкими, так как снижаются накладные расходы на системные вызовы ядра. Поэтому CGI-скрипты, выводящие всё за один раз, могут быть быстрее тех, что выводят много маленьких фрагментов.152153Также стоит использовать основные возможности Python там, где это уместно. Например, срезы позволяют программам разрезать списки и другие объекты-последовательности за один такт главного цикла интерпретатора благодаря высокооптимизированным реализациям на C. Итак, чтобы получить тот же эффект, что и:154155```python156L2 = []157for i in range[3]:158    L2.append(L1[i])159```160161гораздо короче и намного быстрее использовать162163```python164L2 = list(L1[:3])  # "list" избыточен, если L1 является списком.165```166167Обратите внимание, что функционально-ориентированные встроенные функции, такие как [`map()`](https://python-all.ru/2.6/library/functions.html#map), [`zip()`](https://python-all.ru/2.6/library/functions.html#zip) и им подобные, могут быть удобным ускорителем для циклов, выполняющих одну задачу. Например, чтобы попарно объединить элементы двух списков:168169```python170>>> zip([1, 2, 3], [4, 5, 6])171[(1, 4), (2, 5), (3, 6)]172```173174или для вычисления нескольких синусов:175176```python177>>> map(math.sin, (1, 2, 3, 4))178[0.841470984808, 0.909297426826, 0.14112000806, -0.756802495308]179```180181В таких случаях операция выполняется очень быстро.182183Другие примеры включают `join()` и `split()` [*методы строковых объектов*](https://python-all.ru/2.6/library/stdtypes.html#string-methods). Например, если s1..s7 – большие (10K+) строки, то `"".join([s1,s2,s3,s4,s5,s6,s7])` может быть значительно быстрее, чем очевидное `s1+s2+s3+s4+s5+s6+s7`, поскольку «суммирование» будет вычислять много подывыражений, тогда как `join()` выполняет всё копирование за один проход. Для манипуляции строками используйте `replace()` и `format()` [*методы строковых объектов*](https://python-all.ru/2.6/library/stdtypes.html#string-methods). Используйте регулярные выражения только тогда, когда вы не работаете с постоянными строковыми шаблонами. Вы по-прежнему можете использовать [*старые операции со знаком %*](https://python-all.ru/2.6/library/stdtypes.html#string-formatting) `string % tuple` и `string % dictionary`.184185Обязательно используйте встроенный метод `list.sort()` для сортировки и обратитесь к [краткому руководству по сортировке](https://python-all.ru/2.6/faq/programming.html) за примерами умеренно продвинутого использования. `list.sort()` превосходит другие методы сортировки во всех, кроме самых крайних, случаях.186187Ещё один распространённый приём – выносить циклы в функции или методы. Например, предположим, программа выполняется медленно, и с помощью профилировщика определено, что функция Python `ff()` вызывается много раз. Если замечено, что `ff()`:188189```python190def ff(x):191    ... # выполнить действия с x, вычисляя результат...192    return result193```194195склонна вызываться в циклах наподобие:196197```python198list = map(ff, oldlist)199```200201или:202203```python204for x in sequence:205    value = ff(x)206    ... # выполнить действия со значением...207```208209тогда часто можно устранить накладные расходы на вызов функции, переписав `ff()` следующим образом:210211```python212def ffseq(seq):213    resultseq = []214    for x in seq:215        ... # выполнить действия с x, вычисляя результат...216        resultseq.append(result)217    return resultseq218```219220и переписать два примера в `list = ffseq(oldlist)` и в:221222```python223for value in ffseq(sequence):224    ... # выполнить действия со значением...225```226227Одиночные вызовы `ff(x)` преобразуются в `ffseq([x])[0]` с небольшими накладными расходами. Разумеется, этот приём подходит не всегда, и существуют другие варианты, которые можно придумать.228229Можно повысить производительность, явно сохраняя результаты поиска функции или метода в локальной переменной. Цикл наподобие:230231```python232for key in token:233    dict[key] = dict.get(key, 0) + 1234```235236разрешает `dict.get` на каждой итерации. Если метод не меняется, немного более быстрая реализация:237238```python239dict_get = dict.get  # найти метод один раз240for key in token:241    dict[key] = dict_get(key, 0) + 1242```243244Аргументы по умолчанию можно использовать для однократного определения значений на этапе компиляции, а не во время выполнения. Это возможно только для функций или объектов, которые не будут изменяться во время выполнения программы, например замена245246```python247def degree_sin(deg):248    return math.sin(deg * math.pi / 180.0)249```250251на252253```python254def degree_sin(deg, factor=math.pi/180.0, sin=math.sin):255    return sin(deg * factor)256```257258Поскольку этот приём использует аргументы по умолчанию для значений, которые не должны изменяться, его следует использовать только в тех случаях, когда не нужно беспокоиться о том, что API может оказаться запутанным для пользователей.259260## [Ядро языка](https://python-all.ru/2.6/faq/programming.html#id8)261262### [Почему возникает UnboundLocalError, если переменная содержит значение?](https://python-all.ru/2.6/faq/programming.html#id9)263264Может быть неожиданным получить ошибку UnboundLocalError в ранее работавшем коде после добавления оператора присваивания где-то в теле функции.265266Этот код:267268```python269>>> x = 10270>>> def bar():271...     print x272>>> bar()27310274```275276работает, но этот код:277278```python279>>> x = 10280>>> def foo():281...     print x282...     x += 1283```284285приводит к ошибке UnboundLocalError:286287```python288>>> foo()289Traceback (most recent call last):290  ...291UnboundLocalError: local variable 'x' referenced before assignment292```293294Это происходит потому, что при присваивании значения переменной в области видимости эта переменная становится локальной для этой области и затеняет любую одноимённую переменную во внешней области. Поскольку последний оператор в foo присваивает новое значение `x`, компилятор распознаёт её как локальную переменную. Следовательно, когда более ранний `print x` пытается вывести неинициализированную локальную переменную, возникает ошибка.295296В приведённом выше примере можно получить доступ к переменной внешней области, объявив её глобальной:297298```python299>>> x = 10300>>> def foobar():301...     global x302...     print x303...     x += 1304>>> foobar()30510306```307308Такое явное объявление необходимо, чтобы напомнить: в отличие от внешне похожей ситуации с переменными класса и экземпляра, здесь фактически изменяется значение переменной во внешней области видимости:309310```python311>>> print x31211313```314315### [Каковы правила использования локальных и глобальных переменных в Python?](https://python-all.ru/2.6/faq/programming.html#id10)316317В Python переменные, которые используются только внутри функции, неявно считаются глобальными. Если переменной присваивается новое значение в любом месте тела функции, она считается локальной. Если переменной когда-либо присваивается новое значение внутри функции, она неявно является локальной, и её нужно явно объявить как 'global'.318319Хотя сначала это может показаться удивительным, небольшое размышление всё объясняет. С одной стороны, требование [`global`](https://python-all.ru/2.6/reference/simple_stmts.html#global) для присваиваемых переменных предотвращает непреднамеренные побочные эффекты. С другой стороны, если бы `global` требовалось для всех глобальных ссылок, вам пришлось бы использовать `global` постоянно. Пришлось бы объявлять как глобальные каждую ссылку на встроенную функцию или компонент импортированного модуля. Такой беспорядок свёл бы на нет полезность объявления `global` для выявления побочных эффектов.320321### [Как разделять глобальные переменные между модулями?](https://python-all.ru/2.6/faq/programming.html#id11)322323Общепринятый способ обмена информацией между модулями в рамках одной программы – создать специальный модуль (часто называемый config или cfg). Достаточно импортировать модуль config во все модули приложения, и он станет доступен как глобальное имя. Поскольку у каждого модуля существует только один экземпляр, любые изменения объекта модуля отражаются везде. Например:324325config.py:326327```python328x = 0   # Значение по умолчанию для параметра конфигурации 'x'329```330331mod.py:332333```python334import config335config.x = 1336```337338main.py:339340```python341import config342import mod343print config.x344```345346Обратите внимание: использование модуля также является основой для реализации паттерна Singleton по той же причине.347348### [Каковы «лучшие практики» использования import в модуле?](https://python-all.ru/2.6/faq/programming.html#id12)349350В общем случае не используйте `from modulename import *`. Это засоряет пространство имён импортирующего модуля. Некоторые избегают этой идиомы даже с теми немногочисленными модулями, которые спроектированы для импорта таким образом. К модулям, спроектированным таким образом, относятся [`Tkinter`](https://python-all.ru/2.6/library/tkinter.html#module-Tkinter) и [`threading`](https://python-all.ru/2.6/library/threading.html#module-threading).351352Импортируйте модули в начале файла. Так сразу становится ясно, какие ещё модули требуются вашему коду, и не возникает вопросов, находится ли имя модуля в области видимости. Использование одного импорта на строку упрощает добавление и удаление импортов, а использование нескольких импортов в одной строке экономит место на экране.353354Рекомендуется импортировать модули в следующем порядке:3553561. модули стандартной библиотеки – например, `sys`, `os`, `getopt`, `re`3572. модули сторонних библиотек (всё, установленное в каталог site-packages Python), например mx.DateTime, ZODB, PIL.Image и т.д.3583. модули локальной разработки359360Никогда не используйте относительные импорты пакетов. Если вы пишете код, находящийся в модуле `package.sub.m1`, и хотите импортировать `package.sub.m2`, не пишите просто `import m2`, даже если это допустимо. Вместо этого пишите `from package.sub import m2`. Относительные импорты могут привести к двукратной инициализации модуля, что вызывает запутанные ошибки. Подробности см. в [**PEP 328**](https://python-all.ru/2.6/faq/programming.html).361362Иногда импорты приходится переносить внутрь функции или класса, чтобы избежать проблем с циклическими импортами. Gordon McMillan говорит:363364> Циклические импорты нормально работают, когда оба модуля используют форму импорта “import \<module\>”. Они перестают работать, когда второй модуль пытается получить имя из первого (“from module import name”), и импорт находится на верхнем уровне. Это происходит потому, что имена в первом модуле ещё недоступны, так как первый модуль занят импортом второго.365366В этом случае, если второй модуль используется только в одной функции, импорт можно легко перенести в эту функцию. К моменту вызова импорта первый модуль уже завершит инициализацию, и второй модуль сможет выполнить свой импорт.367368Также может потребоваться перенести импорты из верхнего уровня кода, если некоторые модули являются платформозависимыми. В таком случае может быть невозможно импортировать все модули в начале файла. Тогда хорошим решением будет импортировать нужные модули в соответствующем платформозависимом коде.369370Переносите импорты в локальную область видимости, например внутрь определения функции, только если это необходимо для решения проблемы, такой как избежание циклического импорта или попытка сократить время инициализации модуля. Этот метод особенно полезен, если многие импорты не нужны в зависимости от того, как выполняется программа. Возможно, вы также захотите перенести импорты в функцию, если модули используются только внутри неё. Обратите внимание, что загрузка модуля в первый раз может быть дорогой из-за однократной инициализации модуля, но повторная загрузка модуля практически бесплатна – требуется лишь несколько поисков в словаре. Даже если имя модуля вышло из области видимости, модуль, вероятно, доступен в [`sys.modules`](https://python-all.ru/2.6/library/sys.html#sys.modules).371372Если модуль используется только экземплярами определённого класса, то разумно импортировать этот модуль в методе `__init__` класса и затем присвоить модуль переменной экземпляра, чтобы модуль был всегда доступен (через эту переменную экземпляра) в течение времени жизни объекта. Обратите внимание: чтобы отложить импорт до момента создания экземпляра класса, импорт должен находиться внутри метода. Размещение импорта внутри класса, но вне какого-либо метода, всё равно приведёт к тому, что импорт произойдёт при инициализации модуля.373374### [Как передать необязательные или именованные параметры из одной функции в другую?](https://python-all.ru/2.6/faq/programming.html#id13)375376Соберите аргументы с помощью спецификаторов `*` и `**` в списке параметров функции; это даст позиционные аргументы в виде кортежа, а именованные – в виде словаря. Затем вы можете передать эти аргументы при вызове другой функции, используя `*` и `**`:377378```python379def f(x, *args, **kwargs):380    ...381    kwargs['width'] = '14.3c'382    ...383    g(x, *args, **kwargs)384```385386В маловероятном случае, если вам нужна поддержка версий Python старше 2.0, используйте [`apply()`](https://python-all.ru/2.6/library/functions.html#apply):387388```python389def f(x, *args, **kwargs):390    ...391    kwargs['width'] = '14.3c'392    ...393    apply(g, (x,)+args, kwargs)394```395396### [Как написать функцию с выходными параметрами (передача по ссылке)?](https://python-all.ru/2.6/faq/programming.html#id14)397398Помните, что в Python аргументы передаются по присваиванию. Поскольку присваивание лишь создает ссылки на объекты, между именем аргумента в вызывающей и вызываемой функции нет псевдонима, а значит, нет и передачи по ссылке как таковой. Желаемого эффекта можно достичь несколькими способами.3994001. Возвращая кортеж результатов:401402   ```python403   def func2(a, b):404       a = 'new-value'        # a и b – локальные имена405       b = b + 1              # присвоены новым объектам406       return a, b            # вернуть новые значения407408   x, y = 'old-value', 99409   x, y = func2(x, y)410   print x, y                 # вывод: new-value 100411   ```412413   Это почти всегда самое понятное решение.4142. С помощью глобальных переменных. Это не потокобезопасно и не рекомендуется.4153. Передавая изменяемый (изменяемый на месте) объект:416417   ```python418   def func1(a):419       a[0] = 'new-value'     # 'a' ссылается на изменяемый список420       a[1] = a[1] + 1        # изменяет общий объект421422   args = ['old-value', 99]423   func1(args)424   print args[0], args[1]     # вывод: new-value 100425   ```4264. Передавая словарь, который будет изменён:427428   ```python429   def func3(args):430       args['a'] = 'new-value'     # args – изменяемый словарь431       args['b'] = args['b'] + 1   # изменить его на месте432433   args = {'a':' old-value', 'b': 99}434   func3(args)435   print args['a'], args['b']436   ```4375. Или объединив значения в экземпляре класса:438439   ```python440   class callByRef:441       def __init__(self, **args):442           for (key, value) in args.items():443               setattr(self, key, value)444445   def func4(args):446       args.a = 'new-value'        # args – изменяемый callByRef447       args.b = args.b + 1         # изменить объект на месте448449   args = callByRef(a='old-value', b=99)450   func4(args)451   print args.a, args.b452   ```453454   Почти никогда нет веской причины усложнять до такой степени.455456Лучший выбор – вернуть кортеж, содержащий несколько результатов.457458### [Как сделать функцию высшего порядка в Python?](https://python-all.ru/2.6/faq/programming.html#id15)459460У вас есть два варианта: использовать вложенные области видимости или вызываемые объекты. Например, предположим, вы хотите определить `linear(a,b)`, которая возвращает функцию `f(x)`, вычисляющую значение `a*x+b`. Использование вложенных областей видимости:461462```python463def linear(a, b):464    def result(x):465        return a * x + b466    return result467```468469Или используя вызываемый объект:470471```python472class linear:473474    def __init__(self, a, b):475        self.a, self.b = a, b476477    def __call__(self, x):478        return self.a * x + self.b479```480481В обоих случаях482483```python484taxes = linear(0.3, 2)485```486487даёт вызываемый объект, где `taxes(10e6) == 0.3 * 10e6 + 2`.488489Подход с вызываемым объектом имеет недостаток: он немного медленнее и\\nприводит к чуть более длинному коду. Однако обратите внимание, что набор вызываемых объектов\\nможет разделять свою сигнатуру через наследование:490491```python492class exponential(linear):493    # __init__ унаследован494    def __call__(self, x):495        return self.a * (x ** self.b)496```497498Объект может инкапсулировать состояние для нескольких методов:499500```python501class counter:502503    value = 0504505    def set(self, x):506        self.value = x507508    def up(self):509        self.value = self.value + 1510511    def down(self):512        self.value = self.value - 1513514count = counter()515inc, dec, reset = count.up, count.down, count.set516```517518Здесь `inc()`, `dec()` и `reset()` ведут себя как функции, которые совместно используют одну и ту же переменную-счётчик.519520### [Как скопировать объект в Python?](https://python-all.ru/2.6/faq/programming.html#id16)521522В общем случае попробуйте [`copy.copy()`](https://python-all.ru/2.6/library/copy.html#copy.copy) или [`copy.deepcopy()`](https://python-all.ru/2.6/library/copy.html#copy.deepcopy). Не все объекты можно копировать, но большинство можно.523524Некоторые объекты копировать проще. У словарей есть метод [`copy()`](https://python-all.ru/2.6/library/stdtypes.html#dict.copy):525526```python527newdict = olddict.copy()528```529530Последовательности можно скопировать срезом:531532```python533new_l = l[:]534```535536### [Как найти методы или атрибуты объекта?](https://python-all.ru/2.6/faq/programming.html#id17)537538Для экземпляра x пользовательского класса `dir(x)` возвращает отсортированный по алфавиту список имён, содержащий атрибуты экземпляра, а также методы и атрибуты, определённые в его классе.539540### [Как код может узнать имя объекта?](https://python-all.ru/2.6/faq/programming.html#id18)541542Вообще говоря, нет, потому что у объектов на самом деле нет имён. По сути, присваивание всегда связывает имя со значением; то же верно для инструкций `def` и `class`, но в этом случае значением является вызываемый объект. Рассмотрим следующий код:543544```python545class A:546    pass547548B = A549550a = B()551b = a552print b553<__main__.A instance at 0x16D07CC>554print a555<__main__.A instance at 0x16D07CC>556```557558Можно утверждать, что у класса есть имя: даже если он привязан к двум именам и вызывается через имя B, созданный экземпляр всё равно будет определён как экземпляр класса A. Однако невозможно сказать, какое имя у экземпляра – a или b, поскольку оба имени привязаны к одному и тому же значению.559560Вообще говоря, коду не требуется «знать имена» конкретных значений. Если вы не пишете намеренно интроспективные программы, это обычно указывает на то, что стоит изменить подход.561562В comp.lang.python Фредрик Лунд однажды привёл отличную аналогию в ответ на этот вопрос:563564> Точно так же, как вы узнаёте имя кота, которого нашли на крыльце: сам кот (объект) не может сказать вам своего имени, и ему на это всё равно – так что единственный способ узнать, как его зовут, – спросить всех соседей (пространства имён), не их ли это кот (объект)...565>566> ...и не удивляйтесь, если окажется, что он известен под многими именами – или вообще без имени!567568### [Что не так с приоритетом оператора-запятой?](https://python-all.ru/2.6/faq/programming.html#id19)569570Запятая в Python – не оператор. Рассмотрим такой сеанс:571572```python573>>> "a" in "b", "a"574(False, 'a')575```576577Поскольку запятая – не оператор, а разделитель между выражениями, приведённый выше код выполняется так, как если бы вы ввели:578579```python580>>> ("a" in "b"), "a"581```582583а не:584585```python586>>> "a" in ("b", "a")587```588589То же самое верно для различных операторов присваивания (`=`, `+=` и т. д.). Они не являются операторами в полном смысле, а представляют собой синтаксические разделители в операторах присваивания.590591### [Существует ли аналог тернарного оператора «?:» из C?](https://python-all.ru/2.6/faq/programming.html#id20)592593Да, эта возможность была добавлена в Python 2.5. Синтаксис выглядел бы так:594595```python596[on_true] if [expression] else [on_false]597598x, y = 50, 25599600small = x if x < y else y601```602603Для версий до 2.5 ответ был бы «Нет».604605Во многих случаях можно имитировать `a ? b : c` с помощью `a and b or c`, но есть один недостаток: если *b* равно нулю (или пусто, или `None` – что угодно, дающее ложь при проверке), то будет выбрано *c*. Во многих случаях можно, взглянув на код, доказать, что такого не произойдёт (например, если *b* – константа или имеет тип, который никогда не может быть ложным), но в общем случае это может быть проблемой.606607Тим Питерс (который предпочёл бы, чтобы это был Стив Маевски) предложил следующее решение: `(a and [b] or [c])[0]`. Поскольку `[b]` – одноэлементный список, он никогда не бывает ложным, поэтому ошибочная ветвь никогда не выбирается; а затем применение `[0]` ко всему этому даёт *b* или *c*, которое действительно нужно. Уродливо, но это спасает в тех редких случаях, когда переписывать код с использованием 'if' действительно неудобно.608609Лучший подход – обычно написать простой оператор `if...else`. Другое решение – реализовать оператор `?:` как функцию:610611```python612def q(cond, on_true, on_false):613    if cond:614        if not isfunction(on_true):615            return on_true616        else:617            return on_true()618    else:619        if not isfunction(on_false):620            return on_false621        else:622            return on_false()623```624625В большинстве случаев b и c передаются напрямую: `q(a, b, c)`. Чтобы избежать вычисления b или c, когда они не должны вычисляться, оберните их в лямбда-функцию, например: `q(a, lambda: b, lambda: c)`.626627Неоднократно задавался вопрос *почему* в Python нет условного выражения if-then-else. На это есть несколько ответов: многие языки прекрасно обходятся без него; такое выражение может легко привести к менее читаемому коду; не было найдено достаточно «питонического» синтаксиса; поиск по стандартной библиотеке показал, что удивительно мало мест, где использование условного выражения сделало бы код более понятным.628629В 2002 году был написан [**PEP 308**](https://python-all.ru/2.6/faq/programming.html), в котором предлагалось несколько возможных синтаксисов, и сообщество попросили проголосовать. Голосование не дало однозначного результата. Большинству людей нравился один из синтаксисов, но также они ненавидели другие синтаксисы; многие голоса показывали, что люди предпочитают отсутствие тернарного оператора, чем наличие синтаксиса, который им не нравится.630631### [Можно ли писать запутанные однострочники на Python?](https://python-all.ru/2.6/faq/programming.html#id21)632633Да. Обычно это делается путём вложения [`lambda`](https://python-all.ru/2.6/reference/expressions.html#lambda) в [`lambda`](https://python-all.ru/2.6/reference/expressions.html#lambda). Смотрите следующие три примера, автор Ulf Bartelt:634635```python636# Простые числа < 1000637print filter(None,map(lambda y:y*reduce(lambda x,y:x*y!=0,638map(lambda x,y=y:y%x,range(2,int(pow(y,0.5)+1))),1),range(2,1000)))639640# Первые 10 чисел Фибоначчи641print map(lambda x,f=lambda x,f:(f(x-1,f)+f(x-2,f)) if x>1 else 1: f(x,f),642range(10))643644# Множество Мандельброта645print (lambda Ru,Ro,Iu,Io,IM,Sx,Sy:reduce(lambda x,y:x+y,map(lambda y,646Iu=Iu,Io=Io,Ru=Ru,Ro=Ro,Sy=Sy,L=lambda yc,Iu=Iu,Io=Io,Ru=Ru,Ro=Ro,i=IM,647Sx=Sx,Sy=Sy:reduce(lambda x,y:x+y,map(lambda x,xc=Ru,yc=yc,Ru=Ru,Ro=Ro,648i=i,Sx=Sx,F=lambda xc,yc,x,y,k,f=lambda xc,yc,x,y,k,f:(k<=0)or (x*x+y*y649>=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(65064+F(Ru+x*(Ro-Ru)/Sx,yc,0,0,i)),range(Sx))):L(Iu+y*(Io-Iu)/Sy),range(Sy651))))(-2.1, 0.7, -1.2, 1.2, 30, 80, 24)652#    \___ ___/  \___ ___/  |   |   |__ линии на экране653#        V          V      |   |______ столбцы на экране654#        |          |      |__________ максимум "iterations"655#        |          |_________________ диапазон по оси Y656#        |____________________________ диапазон по оси X657```658659Не пытайтесь повторить это дома, дети!660661## [Числа и строки](https://python-all.ru/2.6/faq/programming.html#id22)662663### [Как задать шестнадцатеричные и восьмеричные целые числа?](https://python-all.ru/2.6/faq/programming.html#id23)664665Чтобы задать восьмеричное число, поставьте перед восьмеричным значением ноль, а затем строчную или прописную букву «o». Например, чтобы присвоить переменной «a» восьмеричное значение «10» (8 в десятичной системе), введите:666667```python668>>> a = 0o10669>>> a6708671```672673Шестнадцатеричные числа задаются так же просто. Просто поставьте перед шестнадцатеричным числом ноль, а затем строчную или прописную «x». Шестнадцатеричные цифры можно указывать в нижнем или верхнем регистре. Например, в интерпретаторе Python:674675```python676>>> a = 0xa5677>>> a678165679>>> b = 0XB2680>>> b681178682```683684### [Почему -22 // 10 возвращает -3?](https://python-all.ru/2.6/faq/programming.html#id24)685686Это в первую очередь обусловлено желанием, чтобы `i % j` имел тот же знак, что и `j`. Если вы хотите этого, а также хотите:687688```python689i == (i // j) * j + (i % j)690```691692тогда целочисленное деление должно возвращать floor (целую часть с округлением вниз). C также требует выполнения этого тождества, и тогда компиляторы, которые обрезают `i // j`, должны сделать так, чтобы `i % j` имел тот же знак, что и `i`.693694Существует мало реальных случаев использования `i % j`, когда `j` отрицательно. Когда `j` положительно, таких случаев много, и практически во всех из них полезнее, чтобы `i % j` было равно `>= 0`. Если часы показывают 10 сейчас, что они показывали 200 часов назад? `-190 % 12 == 2` полезно; `-190 % 12 == -10` – это ошибка, которая только и ждёт, чтобы проявиться.695696> **Примечание**697>698> В Python 2 `a / b` возвращает то же самое, что и `a // b`, если `__future__.division` не действует. Это также известно как «классическое» деление.699700### [Как преобразовать строку в число?](https://python-all.ru/2.6/faq/programming.html#id25)701702Для целых чисел используйте встроенный конструктор типа [`int()`](https://python-all.ru/2.6/library/functions.html#int), например `int('144') == 144`. Аналогично [`float()`](https://python-all.ru/2.6/library/functions.html#float) преобразует в число с плавающей точкой, например `float('144') == 144.0`.703704По умолчанию эти функции интерпретируют число как десятичное, так что `int('0144') == 144` и `int('0x144')` вызывают [`ValueError`](https://python-all.ru/2.6/library/exceptions.html#exceptions.ValueError). `int(string, base)` принимает основание системы счисления в качестве второго необязательного аргумента, поэтому `int('0x144', 16) == 324`. Если указать основание 0, число интерпретируется по правилам Python: ведущий '0' означает восьмеричное, а '0x' – шестнадцатеричное.705706Не используйте встроенную функцию [`eval()`](https://python-all.ru/2.6/library/functions.html#eval), если вам нужно только преобразовать строки в числа. [`eval()`](https://python-all.ru/2.6/library/functions.html#eval) будет значительно медленнее и представляет угрозу безопасности: кто-то может передать вам Python-выражение с нежелательными побочными эффектами. Например, кто-то может передать `__import__('os').system("rm -rf $HOME")`, что удалит ваш домашний каталог.707708[`eval()`](https://python-all.ru/2.6/library/functions.html#eval) также интерпретирует числа как выражения Python, так что, например, `eval('09')` выдаёт синтаксическую ошибку, поскольку Python считает числа, начинающиеся с «0», восьмеричными (основание 8).709710### [Как преобразовать число в строку?](https://python-all.ru/2.6/faq/programming.html#id26)711712Для преобразования, например, числа 144 в строку '144', используйте встроенный конструктор типа [`str()`](https://python-all.ru/2.6/library/functions.html#str). Если вам нужно шестнадцатеричное или восьмеричное представление, используйте встроенные функции [`hex()`](https://python-all.ru/2.6/library/functions.html#hex) или [`oct()`](https://python-all.ru/2.6/library/functions.html#oct). Для расширенного форматирования см. раздел [*Синтаксис форматных строк*](https://python-all.ru/2.6/library/string.html#formatstrings), например, `"{:04d}".format(144)` даёт `'0144'`, а `"{:.3f}".format(1/3)` даёт `'0.333'`. Вы также можете использовать [*оператор %*](https://python-all.ru/2.6/library/stdtypes.html#string-formatting) для строк. Подробности см. в справочном руководстве по библиотеке.713714### [Как изменить строку на месте?](https://python-all.ru/2.6/faq/programming.html#id27)715716Так сделать нельзя, потому что строки неизменяемы. Если нужен объект с такой возможностью, попробуйте преобразовать строку в список или используйте модуль array:717718```python719>>> s = "Hello, world"720>>> a = list(s)721>>> print a722['H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd']723>>> a[7:] = list("there!")724>>> ''.join(a)725'Hello, there!'726727>>> import array728>>> a = array.array('c', s)729>>> print a730array('c', 'Hello, world')731>>> a[0] = 'y' ; print a732array('c', 'yello world')733>>> a.tostring()734'yello, world'735```736737### [Как использовать строки для вызова функций/методов?](https://python-all.ru/2.6/faq/programming.html#id28)738739Существует несколько приёмов.740741- Лучший из них – использовать словарь, сопоставляющий строки с функциями. Главное преимущество этого подхода в том, что строки не обязаны совпадать с именами функций. Это также основной способ эмуляции конструкции case:742743  ```python744  def a():745      pass746747  def b():748      pass749750  dispatch = {'go': a, 'stop': b}  # Обратите внимание на отсутствие скобок для функций751752  dispatch[get_input()]()  # Обратите внимание на завершающие скобки для вызова функции753  ```754- Используйте встроенную функцию [`getattr()`](https://python-all.ru/2.6/library/functions.html#getattr):755756  ```python757  import foo758  getattr(foo, 'bar')()759  ```760761  Обратите внимание, что [`getattr()`](https://python-all.ru/2.6/library/functions.html#getattr) работает с любым объектом, включая классы, экземпляры классов, модули и т.д.762763  Это используется в нескольких местах стандартной библиотеки, например:764765  ```python766  class Foo:767      def do_foo(self):768          ...769770      def do_bar(self):771          ...772773  f = getattr(foo_instance, 'do_' + opname)774  f()775  ```776- Используйте [`locals()`](https://python-all.ru/2.6/library/functions.html#locals) или [`eval()`](https://python-all.ru/2.6/library/functions.html#eval) для разрешения имени функции:777778  ```python779  def myFunc():780      print "hello"781782  fname = "myFunc"783784  f = locals()[fname]785  f()786787  f = eval(fname)788  f()789  ```790791  Примечание: использование [`eval()`](https://python-all.ru/2.6/library/functions.html#eval) медленно и опасно. Если у вас нет полного контроля над содержимым строки, кто-то может передать строку, которая приведёт к выполнению произвольной функции.792793### [Существует ли аналог функции chomp() из Perl для удаления завершающих символов новой строки из строк?](https://python-all.ru/2.6/faq/programming.html#id29)794795Начиная с Python 2.2, можно использовать `S.rstrip("\r\n")` для удаления всех вхождений любого терминатора строки в конце строки `S` без удаления других завершающих пробелов. Если строка `S` состоит более чем из одной строки и содержит несколько пустых строк в конце, терминаторы всех пустых строк будут удалены:796797```python798>>> lines = ("line 1 \r\n"799...          "\r\n"800...          "\r\n")801>>> lines.rstrip("\n\r")802'line 1 '803```804805Так как это обычно требуется только при построчном чтении текста, использование `S.rstrip()` таким образом вполне эффективно.806807Для более старых версий Python есть две частичные замены:808809- Если нужно удалить все завершающие пробелы, используйте метод `rstrip()` строковых объектов. Он удаляет все завершающие пробелы, а не только один символ новой строки.810- Если же строка `S` состоит только из одной строки, используйте `S.splitlines()[0]`.811812### [Существует ли аналог функций scanf() или sscanf()?](https://python-all.ru/2.6/faq/programming.html#id30)813814Прямого аналога нет.815816Для простого разбора ввода обычно проще всего разбить строку на слова, разделённые пробелами, с помощью метода [`split()`](https://python-all.ru/2.6/library/stdtypes.html#str.split) строковых объектов, а затем преобразовать десятичные строки в числа с помощью [`int()`](https://python-all.ru/2.6/library/functions.html#int) или [`float()`](https://python-all.ru/2.6/library/functions.html#float). `split()` поддерживает необязательный параметр "sep", который полезен, если строка использует не пробелы в качестве разделителя.817818Для более сложного разбора входных данных лучше подходят регулярные выражения – они мощнее, чем `sscanf()` в C, и лучше приспособлены для этой задачи.819820### [Что означает ошибка «UnicodeError: ASCII \[decoding,encoding\] error: ordinal not in range(128)»?](https://python-all.ru/2.6/faq/programming.html#id31)821822Эта ошибка означает, что ваша установка Python может обрабатывать только 7-битные строки ASCII. Есть несколько способов исправить или обойти проблему.823824Если ваши программы должны обрабатывать данные в произвольных кодировках символов, окружение, в котором работает приложение, обычно определяет кодировку передаваемых данных. Необходимо преобразовать входные данные в строки Unicode, используя эту кодировку. Например, программа, обрабатывающая электронную почту или веб-ввод, обычно находит информацию о кодировке в заголовках Content-Type. Затем это можно использовать для правильного преобразования входных данных в Unicode. Предполагая, что строка, на которую ссылается `value`, закодирована в UTF-8:825826```python827value = unicode(value, "utf-8")828```829830вернёт объект Unicode. Если данные некорректно закодированы в UTF-8, приведённый выше вызов вызовет исключение [`UnicodeError`](https://python-all.ru/2.6/library/exceptions.html#exceptions.UnicodeError).831832Если вы хотите преобразовывать в Unicode только строки, содержащие не-ASCII данные, можно сначала попробовать преобразовать их, считая их ASCII, а затем создавать объекты Unicode, если это не удалось:833834```python835try:836    x = unicode(value, "ascii")837except UnicodeError:838    value = unicode(value, "utf-8")839else:840    # значение было допустимыми ASCII-данными841    pass842```843844Можно задать кодировку по умолчанию в файле `sitecustomize.py`, входящем в состав библиотеки Python. Однако это не рекомендуется, так как изменение общепринятой кодировки по умолчанию может привести к сбоям в модулях расширения сторонних разработчиков.845846Обратите внимание, что в Windows существует кодировка «mbcs», которая использует кодировку, специфичную для текущей локали. Во многих случаях, особенно при работе с COM, она может быть подходящей кодировкой по умолчанию.847848## [Последовательности (кортежи/списки)](https://python-all.ru/2.6/faq/programming.html#id32)849850### [Как преобразовывать кортежи и списки друг в друга?](https://python-all.ru/2.6/faq/programming.html#id33)851852Конструктор типа `tuple(seq)` преобразует любую последовательность (на самом деле, любой итерируемый объект) в кортеж с теми же элементами в том же порядке.853854Например, `tuple([1, 2, 3])` даёт `(1, 2, 3)`, а `tuple('abc')` даёт `('a', 'b', 'c')`. Если аргумент уже является кортежем, то копия не создаётся, а возвращается тот же объект, поэтому вызов [`tuple()`](https://python-all.ru/2.6/library/functions.html#tuple) дёшев, если не уверены, что объект уже кортеж.855856Конструктор типа `list(seq)` преобразует любую последовательность или итерируемый объект в список с теми же элементами в том же порядке. Например, `list((1, 2, 3))` даёт `[1, 2, 3]`, а `list('abc')` даёт `['a', 'b', 'c']`. Если аргумент уже список, то создаётся копия, как и в случае `seq[:]`.857858### [Что такое отрицательный индекс?](https://python-all.ru/2.6/faq/programming.html#id34)859860Последовательности Python индексируются положительными и отрицательными числами. Для положительных чисел 0 – это первый индекс, 1 – второй и т.д. Для отрицательных индексов -1 – это последний, -2 – предпоследний и т.д. Считайте, что `seq[-n]` эквивалентно `seq[len(seq)-n]`.861862Использование отрицательных индексов может быть очень удобным. Например, `S[:-1]` – это вся строка, кроме последнего символа, что полезно для удаления завершающего символа новой строки.863864### [Как перебрать последовательность в обратном порядке?](https://python-all.ru/2.6/faq/programming.html#id35)865866Используйте встроенную функцию [`reversed()`](https://python-all.ru/2.6/library/functions.html#reversed), которая появилась в Python 2.4:867868```python869for x in reversed(sequence):870    ... # выполнить действие с x...871```872873Это не затронет исходную последовательность, а создаст новую копию с обратным порядком для итерации.874875В Python 2.3 можно использовать расширенный синтаксис срезов:876877```python878for x in sequence[::-1]:879    ... # выполнить действие с x...880```881882### [Как удалить дубликаты из списка?](https://python-all.ru/2.6/faq/programming.html#id36)883884См. Python Cookbook, где подробно рассматриваются многие способы сделать это:885886> [http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52560](https://python-all.ru/2.6/faq/programming.html)887888Если перестановка элементов списка не страшна, отсортируйте его, а затем просмотрите с конца, удаляя дубликаты по ходу:889890```python891if mylist:892    mylist.sort()893    last = mylist[-1]894    for i in range(len(mylist)-2, -1, -1):895        if last == mylist[i]:896            del mylist[i]897        else:898            last = mylist[i]899```900901Если все элементы списка могут быть использованы как ключи словаря (то есть они все хешируемы), это часто быстрее902903```python904d = {}905for x in mylist:906    d[x] = 1907mylist = list(d.keys())908```909910В Python 2.5 и новее вместо этого можно сделать следующее:911912```python913mylist = list(set(mylist))914```915916Это преобразует список во множество, удаляя дубликаты, а затем обратно в список.917918### [Как создать массив в Python?](https://python-all.ru/2.6/faq/programming.html#id37)919920Используйте список:921922```python923["this", 1, "is", "an", "array"]924```925926По временно́й сложности списки эквивалентны массивам C или Pascal; основное отличие в том, что список Python может содержать объекты разных типов.927928Модуль `array` также предоставляет методы для создания массивов фиксированных типов с компактным представлением, но они медленнее индексируются, чем списки. Также обратите внимание, что расширения Numeric и другие определяют структуры, похожие на массивы, с различными характеристиками.929930Чтобы получить связные списки в стиле Lisp, можно эмулировать ячейки cons с помощью кортежей:931932```python933lisp_list = ("like",  ("this",  ("example", None) ) )934```935936Если нужна изменяемость, можно использовать списки вместо кортежей. Здесь аналог lisp car – это `lisp_list[0]`, а аналог cdr – `lisp_list[1]`. Делайте так, только если уверены, что это действительно необходимо, потому что обычно это намного медленнее, чем использование списков Python.937938### [Как создать многомерный список?](https://python-all.ru/2.6/faq/programming.html#id38)939940Вероятно, вы пытались создать многомерный массив так:941942```python943A = [[None] * 2] * 3944```945946Если вывести его, выглядит правильно:947948```python949>>> A950[[None, None], [None, None], [None, None]]951```952953Но когда вы присваиваете значение, оно появляется в нескольких местах:954955```python956>>> A[0][0] = 5957>>> A958[[5, None], [5, None], [5, None]]959```960961Причина в том, что размножение списка с помощью `*` не создаёт копии, а только ссылки на существующие объекты. `*3` создаёт список из 3 ссылок на один и тот же список длины два. Изменения в одной строке отразятся во всех строках, что почти наверняка не то, что нужно.962963Рекомендуемый подход – сначала создать список нужной длины, а затем заполнить каждый элемент заново созданным списком:964965```python966A = [None] * 3967for i in range(3):968    A[i] = [None] * 2969```970971Это порождает список, содержащий 3 разных списка длины два. Также можно использовать списковое включение:972973```python974w, h = 2, 3975A = [[None] * w for i in range(h)]976```977978Или можно использовать расширение, предоставляющее тип данных матрица; наиболее известно [Numeric Python](https://python-all.ru/2.6/faq/programming.html).979980### [Как применить метод к последовательности объектов?](https://python-all.ru/2.6/faq/programming.html#id39)981982Используйте списковое включение:983984```python985result = [obj.method() for obj in mylist]986```987988В более общем случае можно попробовать следующую функцию:989990```python991def method_map(objects, method, arguments):992    """method_map([a,b], "meth", (1,2)) даёт [a.meth(1,2), b.meth(1,2)]"""993    nobjects = len(objects)994    methods = map(getattr, objects, [method]*nobjects)995    return map(apply, methods, [arguments]*nobjects)996```997998## [Словари](https://python-all.ru/2.6/faq/programming.html#id40)9991000### [Как сделать так, чтобы ключи словаря отображались в постоянном порядке?](https://python-all.ru/2.6/faq/programming.html#id41)10011002Невозможно. Словари хранят ключи в непредсказуемом порядке, поэтому порядок отображения элементов словаря будет таким же непредсказуемым.10031004Это может раздражать, если вы хотите сохранить версию для печати в файл, внести некоторые изменения, а затем сравнить её с другим распечатанным словарём. В этом случае используйте модуль `pprint` для форматированного вывода словаря; элементы будут представлены в порядке, отсортированном по ключу.10051006Более сложное решение – создать подкласс `dict` для создания класса `SortedDict`, который выводит себя в предсказуемом порядке. Вот одна простоватая реализация такого класса:10071008```python1009class SortedDict(dict):1010    def __repr__(self):1011        keys = sorted(self.keys())1012        result = ("{!r}: {!r}".format(k, self[k]) for k in keys)1013        return "{{{}}}".format(", ".join(result))10141015    __str__ = __repr__1016```10171018Это будет работать для многих распространённых ситуаций, которые могут встретиться, хотя это далеко не идеальное решение. Самый большой недостаток: если некоторые значения в словаре сами являются словарями, их значения не будут представлены в каком-либо определённом порядке.10191020### [Я хочу выполнить сложную сортировку: можно ли сделать преобразование Шварца в Python?](https://python-all.ru/2.6/faq/programming.html#id42)10211022Этот метод, приписываемый Рэндалу Шварцу из сообщества Perl, сортирует элементы списка по метрике, которая отображает каждый элемент в его "значение сортировки". В Python просто используйте аргумент `key` для метода `sort()`:10231024```python1025Isorted = L[:]1026Isorted.sort(key=lambda s: int(s[10:15]))1027```10281029Аргумент `key` появился в Python 2.4, для более старых версий такую сортировку довольно просто выполнить с помощью списковых включений. Чтобы отсортировать список строк по их значениям в верхнем регистре:10301031```python1032tmp1 = [(x.upper(), x) for x in L]  # Преобразование Шварца1033tmp1.sort()1034Usorted = [x[1] for x in tmp1]1035```10361037Чтобы отсортировать по целочисленному значению подполя, расположенного с 10 по 15 позицию в каждой строке:10381039```python1040tmp2 = [(int(s[10:15]), s) for s in L]  # Преобразование Шварца1041tmp2.sort()1042Isorted = [x[1] for x in tmp2]1043```10441045Обратите внимание, что Isorted также можно вычислить с помощью10461047```python1048def intfield(s):1049    return int(s[10:15])10501051def Icmp(s1, s2):1052    return cmp(intfield(s1), intfield(s2))10531054Isorted = L[:]1055Isorted.sort(Icmp)1056```10571058но поскольку этот метод вызывает `intfield()` много раз для каждого элемента L, он медленнее преобразования Шварца.10591060### [Как отсортировать один список по значениям из другого списка?](https://python-all.ru/2.6/faq/programming.html#id43)10611062Объедините их в единый список кортежей, отсортируйте полученный список, а затем выберите нужный элемент.10631064```python1065>>> list1 = ["what", "I'm", "sorting", "by"]1066>>> list2 = ["something", "else", "to", "sort"]1067>>> pairs = zip(list1, list2)1068>>> pairs1069[('what', 'something'), ("I'm", 'else'), ('sorting', 'to'), ('by', 'sort')]1070>>> pairs.sort()1071>>> result = [ x[1] for x in pairs ]1072>>> result1073['else', 'sort', 'to', 'something']1074```10751076Альтернатива для последнего шага:10771078```python1079>>> result = []1080>>> for p in pairs: result.append(p[1])1081```10821083Если такой вариант кажется вам более читаемым, возможно, вы предпочтёте его итоговому списковому включению. Однако для длинных списков он почти вдвое медленнее. Почему? Во-первых, операция `append()` требует перераспределения памяти, и хотя для этого используются некоторые уловки, чтобы избегать его каждый раз, время от времени это всё же происходит, и это обходится довольно дорого. Во-вторых, выражение «result.append» требует дополнительного поиска атрибута. В-третьих, из-за необходимости совершать все эти вызовы функций скорость снижается.10841085## [Объекты](https://python-all.ru/2.6/faq/programming.html#id44)10861087### [Что такое класс?](https://python-all.ru/2.6/faq/programming.html#id45)10881089Класс – это конкретный тип объекта, создаваемый при выполнении инструкции class. Объекты классов используются как шаблоны для создания объектов-экземпляров, которые содержат как данные (атрибуты), так и код (методы), характерные для данного типа данных.10901091Класс может быть основан на одном или нескольких других классах, называемых его базовыми классами. Он наследует атрибуты и методы своих базовых классов. Это позволяет последовательно уточнять объектную модель с помощью наследования. У вас может быть общий класс `Mailbox`, предоставляющий базовые методы доступа для почтового ящика, и подклассы, такие как `MboxMailbox`, `MaildirMailbox`, `OutlookMailbox`, которые работают с различными конкретными форматами почтовых ящиков.10921093### [Что такое метод?](https://python-all.ru/2.6/faq/programming.html#id46)10941095Метод – это функция некоторого объекта `x`, которую обычно вызывают как `x.name(аргументы...)`. Методы определяются как функции внутри определения класса:10961097```python1098class C:1099    def meth (self, arg):1100        return arg * 2 + self.attribute1101```11021103### [Что такое self?](https://python-all.ru/2.6/faq/programming.html#id47)11041105Self – это всего лишь общепринятое имя для первого аргумента метода. Метод, определённый как `meth(self, a, b, c)`, следует вызывать как `x.meth(a, b, c)` для некоторого экземпляра `x` класса, в котором находится определение; вызываемый метод будет считать, что его вызвали как `meth(x, a, b, c)`.11061107См. также [*Почему self должно явно использоваться в определениях и вызовах методов?*](https://python-all.ru/2.6/faq/design.html#why-self).11081109### [Как проверить, является ли объект экземпляром данного класса или его подкласса?](https://python-all.ru/2.6/faq/programming.html#id48)11101111Используйте встроенную функцию `isinstance(obj, cls)`. Можно проверить, является ли объект экземпляром одного из нескольких классов, передав кортеж вместо одного класса, например `isinstance(obj, (class1, class2, ...))`, а также можно проверить, является ли объект одним из встроенных типов Python, например `isinstance(obj, str)` или `isinstance(obj, (int, long, float, complex))`.11121113Обратите внимание: в большинстве программ [`isinstance()`](https://python-all.ru/2.6/library/functions.html#isinstance) для пользовательских классов используется нечасто. Если вы сами разрабатываете классы, более правильным объектно-ориентированным стилем будет определять в классах методы, инкапсулирующие определённое поведение, вместо проверки класса объекта и выполнения разных действий в зависимости от того, к какому классу он принадлежит. Например, если у вас есть функция, которая делает что-то:11141115```python1116def search(obj):1117    if isinstance(obj, Mailbox):1118        # ... code to search a mailbox1119    elif isinstance(obj, Document):1120        # ... code to search a document1121    elif ...1122```11231124Более правильный подход – определить метод `search()` во всех классах и просто вызывать его:11251126```python1127class Mailbox:1128    def search(self):1129        # ... code to search a mailbox11301131class Document:1132    def search(self):1133        # ... code to search a document11341135obj.search()1136```11371138### [Что такое делегирование?](https://python-all.ru/2.6/faq/programming.html#id49)11391140Делегирование – это объектно-ориентированный приём (также называемый шаблоном проектирования). Допустим, у вас есть объект `x`, и вы хотите изменить поведение только одного из его методов. Можно создать новый класс, который предоставляет новую реализацию интересующего вас метода, а все остальные методы делегирует соответствующим методам объекта `x`.11411142Программисты на Python могут легко реализовать делегирование. Например, следующий класс реализует класс, который ведёт себя как файл, но преобразует все записываемые данные в верхний регистр:11431144```python1145class UpperOut:11461147    def __init__(self, outfile):1148        self._outfile = outfile11491150    def write(self, s):1151        self._outfile.write(s.upper())11521153    def __getattr__(self, name):1154        return getattr(self._outfile, name)1155```11561157Здесь класс `UpperOut` переопределяет метод `write()`, чтобы преобразовывать строку аргумента в верхний регистр перед вызовом базового метода `self.__outfile.write()`. Все остальные методы делегируются базовому объекту `self.__outfile`. Делегирование осуществляется через метод `__getattr__`; обратитесь к [*ссылке на язык*](https://python-all.ru/2.6/reference/datamodel.html#attribute-access) для получения дополнительной информации об управлении доступом к атрибутам.11581159Обратите внимание: в более общих случаях делегирование может усложняться. Когда атрибуты необходимо не только получать, но и устанавливать, класс должен также определить метод [`__setattr__()`](https://python-all.ru/2.6/reference/datamodel.html#object.__setattr__), и делать это нужно аккуратно. Базовая реализация [`__setattr__()`](https://python-all.ru/2.6/reference/datamodel.html#object.__setattr__) примерно эквивалентна следующему:11601161```python1162class X:1163    ...1164    def __setattr__(self, name, value):1165        self.__dict__[name] = value1166    ...1167```11681169Большинство реализаций [`__setattr__()`](https://python-all.ru/2.6/reference/datamodel.html#object.__setattr__) должны изменять `self.__dict__` для хранения локального состояния self, чтобы не вызывать бесконечную рекурсию.11701171### [Как вызвать метод, определённый в базовом классе, из производного класса, который его переопределяет?](https://python-all.ru/2.6/faq/programming.html#id50)11721173Если вы используете классы нового стиля, используйте встроенную функцию [`super()`](https://python-all.ru/2.6/library/functions.html#super):11741175```python1176class Derived(Base):1177    def meth (self):1178        super(Derived, self).meth()1179```11801181Если вы используете классические классы: для определения класса вида `class Derived(Base): ...` вы можете вызвать метод `meth()`, определённый в `Base` (или одном из базовых классов `Base`), как `Base.meth(self, arguments...)`. Здесь `Base.meth` – это несвязанный метод, поэтому необходимо передать аргумент `self`.11821183### [Как организовать код, чтобы было проще изменить базовый класс?](https://python-all.ru/2.6/faq/programming.html#id51)11841185Можно определить псевдоним для базового класса, присвоить ему реальный базовый класс до определения вашего класса и использовать псевдоним во всём классе. Тогда всё, что нужно изменить – это значение, присвоенное псевдониму. Кстати, этот трюк также удобен, если вы хотите динамически (например, в зависимости от доступности ресурсов) выбирать, какой базовый класс использовать. Пример:11861187```python1188BaseAlias = <real base class>11891190class Derived(BaseAlias):1191    def meth(self):1192        BaseAlias.meth(self)1193        ...1194```11951196### [Как создать статические данные класса и статические методы класса?](https://python-all.ru/2.6/faq/programming.html#id52)11971198В Python поддерживаются как статические данные, так и статические методы (в смысле C++ или Java).11991200Для статических данных просто определите атрибут класса. Чтобы присвоить атрибуту новое значение, необходимо явно указать имя класса в присваивании:12011202```python1203class C:1204    count = 0   # количество вызовов C.__init__12051206    def __init__(self):1207        C.count = C.count + 112081209    def getcount(self):1210        return C.count  # или вернуть self.count1211```12121213`c.count` также ссылается на `C.count` для любого `c`, для которого выполняется `isinstance(c, C)`, если только это не переопределено самим объектом `c` или каким-либо классом на пути поиска от `c.__class__` обратно к `C`.12141215Предупреждение: внутри метода C присваивание вида `self.count = 42` создаёт новый, не связанный экземпляр с именем «count» в собственном словаре `self`. Повторное связывание статического имени данных класса всегда должно указывать сам класс, независимо от того, находится ли оно внутри метода или нет:12161217```python1218C.count = 3141219```12201221Статические методы возможны начиная с Python 2.2:12221223```python1224class C:1225    def static(arg1, arg2, arg3):1226        # Нет параметра 'self'!1227        ...1228    static = staticmethod(static)1229```12301231С помощью декораторов Python 2.4 это также можно записать как12321233```python1234class C:1235    @staticmethod1236    def static(arg1, arg2, arg3):1237        # Нет параметра 'self'!1238        ...1239```12401241Однако гораздо более прямолинейный способ получить эффект статического метода – это простая функция уровня модуля:12421243```python1244def getcount():1245    return C.count1246```12471248Если код организован так, что на каждый модуль определён один класс (или тесно связанная иерархия классов), это обеспечивает нужную инкапсуляцию.12491250### [Как перегрузить конструкторы (или методы) в Python?](https://python-all.ru/2.6/faq/programming.html#id53)12511252Этот ответ на самом деле применим ко всем методам, но вопрос обычно возникает в первую очередь в контексте конструкторов.12531254В C++ вы бы написали12551256```c1257class C {1258    C() { cout << "No arguments\n"; }1259    C(int i) { cout << "Argument is " << i << "\n"; }1260}1261```12621263В Python нужно написать один конструктор, который обрабатывает все случаи с помощью аргументов по умолчанию. Например:12641265```python1266class C:1267    def __init__(self, i=None):1268        if i is None:1269            print "No arguments"1270        else:1271            print "Argument is", i1272```12731274Это не полностью эквивалентно, но на практике достаточно близко.12751276Можно также попробовать список аргументов переменной длины, например12771278```python1279def __init__(self, *args):1280    ...1281```12821283Тот же подход работает для всех определений методов.12841285### [Я пытаюсь использовать \_\_spam и получаю ошибку про \_SomeClassName\_\_spam.](https://python-all.ru/2.6/faq/programming.html#id54)12861287Имена переменных с двойным подчёркиванием в начале подвергаются «искажению», что даёт простой, но эффективный способ определения частных переменных класса. Любой идентификатор вида `__spam` (не менее двух ведущих подчёркиваний, не более одного завершающего) текстуально заменяется на `_classname__spam`, где `classname` – это имя текущего класса с удалёнными ведущими подчёркиваниями.12881289Это не гарантирует приватности: внешний пользователь всё равно может намеренно получить доступ к атрибуту «\_classname\_\_spam», а частные значения видны в `__dict__` объекта. Многие программисты Python вообще не утруждают себя использованием частных имён переменных.12901291### [Мой класс определяет \_\_del\_\_, но он не вызывается, когда я удаляю объект.](https://python-all.ru/2.6/faq/programming.html#id55)12921293Для этого есть несколько возможных причин.12941295Оператор [https://python-all.ru/2.6/reference/datamodel.html#object.__del__](https://python-all.ru/2.6/reference/datamodel.html#object.__del__)del не обязательно вызывает `__del__()` – он просто уменьшает счётчик ссылок объекта, и если тот достигает нуля, вызывается [`__del__()`](https://python-all.ru/2.6/reference/datamodel.html#object.__del__).12961297Если ваши структуры данных содержат циклические ссылки (например, дерево, где каждый потомок имеет ссылку на родителя, а каждый родитель – список потомков), счётчики ссылок никогда не обнулятся. Время от времени Python запускает алгоритм для обнаружения таких циклов, но сборщик мусора может запуститься спустя некоторое время после исчезновения последней ссылки на вашу структуру данных, поэтому ваш метод [`__del__()`](https://python-all.ru/2.6/reference/datamodel.html#object.__del__) может быть вызван в неудобный и случайный момент. Это неудобно, если вы пытаетесь воспроизвести проблему. Хуже того, порядок, в котором выполняются методы [`__del__()`](https://python-all.ru/2.6/reference/datamodel.html#object.__del__) объектов, произволен. Вы можете запустить [`gc.collect()`](https://python-all.ru/2.6/library/gc.html#gc.collect), чтобы принудительно выполнить сборку, но существуют *патологические* случаи, когда объекты никогда не будут собраны.12981299Несмотря на сборщик циклов, всё же стоит определять явный метод `close()` для объектов, который следует вызывать, когда объект больше не нужен. Метод `close()` может затем удалять атрибуты, ссылающиеся на подобъекты. Не вызывайте [`__del__()`](https://python-all.ru/2.6/reference/datamodel.html#object.__del__) напрямую – [`__del__()`](https://python-all.ru/2.6/reference/datamodel.html#object.__del__) должен вызывать `close()`, а `close()` должен гарантировать, что его можно вызвать для одного и того же объекта несколько раз.13001301Ещё один способ избежать циклических ссылок – использовать модуль [`weakref`](https://python-all.ru/2.6/library/weakref.html#module-weakref), который позволяет указывать на объекты без увеличения их счётчика ссылок. Например, в древовидных структурах данных для ссылок на родителя и соседей (если они нужны) следует использовать слабые ссылки.13021303Если объект когда-либо был локальной переменной в функции, которая перехватила выражение в блоке except, вполне вероятно, что ссылка на объект всё ещё существует в стековом фрейме этой функции, как часть трассировки стека. Обычно вызов [`sys.exc_clear()`](https://python-all.ru/2.6/library/sys.html#sys.exc_clear) позаботится об этом, очистив последнее записанное исключение.13041305Наконец, если ваш метод [`__del__()`](https://python-all.ru/2.6/reference/datamodel.html#object.__del__) вызывает исключение, в [`sys.stderr`](https://python-all.ru/2.6/library/sys.html#sys.stderr) выводится предупреждение.13061307### [Как получить список всех экземпляров данного класса?](https://python-all.ru/2.6/faq/programming.html#id56)13081309Python не отслеживает все экземпляры класса (или встроенного типа). Можно запрограммировать конструктор класса так, чтобы он отслеживал все экземпляры, сохраняя список слабых ссылок на каждый экземпляр.13101311## [Модули](https://python-all.ru/2.6/faq/programming.html#id57)13121313### [Как создать .pyc-файл?](https://python-all.ru/2.6/faq/programming.html#id58)13141315Когда модуль импортируется впервые (или когда исходный код новее текущего скомпилированного файла), в том же каталоге, что и файл `.py`, должен быть создан файл `.pyc`, содержащий скомпилированный код.13161317Одна из причин, по которой файл `.pyc` может не создаваться, – проблемы с правами доступа к каталогу. Это может произойти, например, если вы разрабатываете как один пользователь, а запускаете как другой, например, при тестировании с веб-сервером. Создание файла .pyc происходит автоматически, если вы импортируете модуль и у Python есть возможность (права, свободное место и т.д.) записать скомпилированный модуль обратно в каталог.13181319Запуск Python на верхнеуровневом скрипте не считается импортом, и файл `.pyc` создан не будет. Например, если у вас есть модуль верхнего уровня `abc.py`, который импортирует другой модуль `xyz.py`, то при запуске abc будет создан `xyz.pyc`, так как xyz импортируется, но файл `abc.pyc` создан не будет, поскольку `abc.py` не импортируется.13201321Если необходимо создать abc.pyc – то есть создать .pyc-файл для модуля, который не импортируется – это можно сделать с помощью модулей [`py_compile`](https://python-all.ru/2.6/library/py_compile.html#module-py_compile) и [`compileall`](https://python-all.ru/2.6/library/compileall.html#module-compileall).13221323Модуль [`py_compile`](https://python-all.ru/2.6/library/py_compile.html#module-py_compile) может вручную компилировать любой модуль. Один из способов – интерактивно использовать функцию `compile()` из этого модуля:13241325```python1326>>> import py_compile1327>>> py_compile.compile('abc.py')1328```13291330Это запишет файл `.pyc` в то же расположение, что и `abc.py` (или вы можете переопределить это с помощью необязательного параметра `cfile`).13311332Вы также можете автоматически скомпилировать все файлы в каталоге или каталогах, используя модуль [`compileall`](https://python-all.ru/2.6/library/compileall.html#module-compileall). Это можно сделать из командной строки, запустив `compileall.py` и указав путь к каталогу, содержащему файлы Python для компиляции:13331334```python1335python -m compileall .1336```13371338### [Как узнать имя текущего модуля?](https://python-all.ru/2.6/faq/programming.html#id59)13391340Модуль может узнать своё собственное имя, обратившись к предопределённой глобальной переменной `__name__`. Если она равна `'__main__'`, программа выполняется как сценарий. Многие модули, которые обычно используются путём импорта, также предоставляют интерфейс командной строки или самопроверку и выполняют этот код только после проверки `__name__`:13411342```python1343def main():1344    print 'Running test...'1345    ...13461347if __name__ == '__main__':1348    main()1349```13501351### [Как сделать модули, которые импортируют друг друга?](https://python-all.ru/2.6/faq/programming.html#id60)13521353Предположим, у вас есть следующие модули:13541355foo.py:13561357```python1358from bar import bar_var1359foo_var = 11360```13611362bar.py:13631364```python1365from foo import foo_var1366bar_var = 21367```13681369Проблема в том, что интерпретатор выполнит следующие шаги:13701371- main импортирует foo1372- Создаются пустые глобальные переменные для foo1373- foo компилируется и начинает выполняться1374- foo импортирует bar1375- Создаются пустые глобальные переменные для bar1376- bar компилируется и начинает выполняться1377- bar импортирует foo (это пустая операция, так как модуль с именем foo уже существует)1378- bar.foo\_var = foo.foo\_var13791380Последний шаг завершается ошибкой, потому что Python ещё не закончил интерпретацию `foo`, и глобальный словарь символов для `foo` всё ещё пуст.13811382То же самое происходит при использовании `import foo` и последующей попытке обратиться к `foo.foo_var` в глобальном коде.13831384Существует (как минимум) три возможных обходных решения этой проблемы.13851386Гвидо ван Россум рекомендует избегать всех случаев использования `from <module> import ...` и размещать весь код внутри функций. Инициализации глобальных переменных и переменных класса должны использовать только константы или встроенные функции. Это означает, что всё из импортированного модуля указывается как `<module>.<name>`.13871388Джим Роскинд предлагает выполнять шаги в следующем порядке в каждом модуле:13891390- экспорт (глобальные переменные, функции и классы, которым не нужны импортированные базовые классы)1391- Операторы `import`1392- активный код (включая глобальные переменные, инициализируемые из импортированных значений).13931394ван Россуму такой подход не очень нравится, потому что импорты оказываются в странном месте, но это работает.13951396Маттиас Урлихс рекомендует перестроить код так, чтобы рекурсивный импорт вообще не требовался.13971398Эти решения не являются взаимоисключающими.13991400### [\_\_import\_\_(‘x.y.z’) возвращает \<module ‘x’\>; как получить z?](https://python-all.ru/2.6/faq/programming.html#id61)14011402Попробуйте:14031404```python1405__import__('x.y.z').y.z1406```14071408В более реалистичных ситуациях, возможно, придётся сделать что-то вроде14091410```python1411m = __import__(s)1412for i in s.split(".")[1:]:1413    m = getattr(m, i)1414```14151416См. `importlib` для удобной функции `import_module()`.14171418### [Когда я редактирую импортированный модуль и повторно импортирую его, изменения не отображаются. Почему это происходит?](https://python-all.ru/2.6/faq/programming.html#id62)14191420Из соображений эффективности и согласованности Python читает файл модуля только при первом импорте модуля. Если бы это было не так, в программе, состоящей из многих модулей, каждый из которых импортирует один и тот же базовый модуль, базовый модуль разбирался бы и переразбирался многократно. Чтобы принудительно перечитать изменённый модуль, сделайте следующее:14211422```python1423import modname1424reload(modname)1425```14261427Предупреждение: этот метод не является абсолютно надёжным. В частности, модули, содержащие операторы типа14281429```python1430from modname import some_objects1431```14321433будут продолжать работать со старой версией импортированных объектов. Если модуль содержит определения классов, существующие экземпляры классов *не* будут обновлены для использования нового определения класса. Это может привести к следующему парадоксальному поведению:14341435```python1436>>> import cls1437>>> c = cls.C()                # Создать экземпляр C1438>>> reload(cls)1439<module 'cls' from 'cls.pyc'>1440>>> isinstance(c, cls.C)       # isinstance ложно?!?1441False1442```14431444Суть проблемы становится ясной, если вывести объекты классов:14451446```python1447>>> c.__class__1448<class cls.C at 0x7352a0>1449>>> cls.C1450<class cls.C at 0x4198d0>1451```1452