Кеннет Рейтц – Автостопом по Python (страница 13)
Используйте синтаксис x in d вместо метода dict.has_key или передавайте аргумент по умолчанию в метод dict.get().
Списковые включения — мощный способ работы со списками (для получения более подробной информации обратитесь к соответствующей статье в руководстве
Используйте функцию enumerate(), чтобы определить свою позицию в списке. Этот вариант выглядит более читаемым, чем создание счетчика, и лучше оптимизирован для итераторов:
>>> a = ["icky", "icky", "icky", "p-tang"]
>>> for i, item in enumerate(a):
… ····print("{i}: {item}".format(i=i, item=item))
…
0: icky
1: icky
2: icky
3: p-tang
Когда логическая строка кода длиннее принятого значения[38], нужно разбить строку на несколько физических строк. Интерпретатор Python объединит следующие друг за другом строки, если последний символ строки — обратный слэш. В некоторых случаях это может оказаться полезным, но такого подхода следует избегать, потому что знак пробела, добавленный в конце строки, разрушит код и может привести к неожиданным последствиям.
Лучшее решение — заключить элементы в круглые скобки. Если интерпретатор Python встретит незакрытую круглую скобку в одной строке, он будет присоединять к ней следующие строки до тех пор, пока скобка не будет закрыта. То же поведение верно для фигурных и квадратных скобок.
Однако зачастую необходимость разбивать длинные логические строки указывает на то, что вы пытаетесь выполнить слишком много действий за раз, что может навредить читаемости.
Идиомы
Несмотря на то что обычно существует всего один очевидный способ решить задачу, код Python, написанный с помощью идиом (
Если вы знаете длину списка или кортежа, можете присвоить имена их элементам с помощью распаковки. Поскольку вы можете указать количество разбиений строки для функций split() и rsplit(), правую сторону выражения присваивания можно разбить только один раз (например, на имя файла и расширение), а левая сторона может содержать оба места назначения одновременно, в правильном порядке. Например, так:
>>> filename, ext = "my_photo.orig.png".rsplit(".", 1)
>>> print(filename, "is a", ext, "file.")
my_photo.orig is a png file.
Вы можете задействовать распаковку для того, чтобы менять местами переменные:
a, b = b, a
Вложенная распаковка также работает:
a, (b, c) = 1, (2, 3)
В Python 3 в PEP 3132 (https://www.python.org/dev/peps/pep-3132/) был представлен новый метод расширенной распаковки:
a, *rest = [1, 2, 3]
# a = 1, rest = [2, 3]
a, *middle, c = [1, 2, 3, 4]
# a = 1, middle = [2, 3], c = 4
Если вам необходимо присвоить какое-то значение во время распаковки, но сама переменная не нужна, воспользуйтесь двойным подчеркиванием (__):
filename = 'foobar.txt'
basename, __, ext = filename.rpartition('.')
Многие руководства по стилю для Python рекомендуют использовать одинарное подчеркивание (_) для подобных переменных вместо двойного (__), о котором говорится здесь. Проблема в том, что одинарное подчеркивание зачастую применяется как псевдоним для функции gettext.gettext() и как интерактивное приглашение сохранить значение последней операции. Двойное подчеркивание выглядит точно так же прозрачно и почти так же удобно, снижает риск случайного переписывания переменной с именем «_» в обоих сценариях.
Используйте оператор списка Python * для того, чтобы создать список, состоящий из одинаковых неизменяемых элементов:
>>> four_nones = [None] * 4
>>> print(four_nones)
[None, None, None, None]
Одинаковые объекты должны иметь одинаковые значения хэша. В документации к Python содержится более подробная информация.
Однако будьте осторожны при работе с изменяемыми объектами: поскольку списки изменяемы, оператор * создаст список, состоящий из
Распространенная идиома для создания строк состоит в том, чтобы использовать функцию str.join() для пустой строки. Данная идиома может быть применена к спискам и кортежам:
>>> letters = ['s', 'p', 'a', 'm']
>>> word = ''.join(letters)
>>> print(word)
spam
Иногда требуется выполнить поиск по коллекции элементов. Изучим два варианта: списки и множества.
Для примера рассмотрим следующий код:
>>> x = list(('foo', 'foo', 'bar', 'baz'))
>>> y = set(('foo', 'foo', 'bar', 'baz'))
>>>
>>> print(x)
['foo', 'foo', 'bar', 'baz']
>>> print(y)
{'foo', 'bar', 'baz'}
>>>
>>> 'foo' in x True
>>> 'foo' in y True
Даже несмотря на то что обе булевых проверки на наличие в списке и множестве выглядят идентично, а foo in y учитывает тот факт, что множества (и словари) в Python являются хэш-таблицами[40], производительность для этих двух примеров будет различной. Python должен пройти по каждому элементу списка в поисках совпадения, на что уходит много времени (это заметно при увеличении размера коллекций). Но поиск ключей во множестве может быть выполнен быстро с помощью поиска по хэшу. Кроме того, множества и словари не могут содержать повторяющихся записей и идентичных ключей. Для получения более подробной информации поинтересуйтесь семинаром на эту тему на ресурсе Stack Overflow (http://stackoverflow.com/questions/513882).
Зачастую блоки try/finally используются для управления ресурсами вроде файлов или блокировок потоков в случае генерации исключений. В PEP 343 (https://www.python.org/dev/peps/pep-0343/) представлены оператор with и протокол управления контекстом (в версиях 2.5 и выше) — идиома, позволяющая заменить блоки try/finally на более читаемый код. Протокол состоит из двух методов, __enter__() и __exit__(), которые при реализации для объекта позволяют использовать этот объект в операторе with, например так:
>>> import threading
>>> some_lock = threading.Lock()
>>>
>>> with some_lock:
… ····# Создать Землю 1, запустить ее на десять миллионов лет…
… ····print(