Эта статья предназначена для новичков в мире Python. Статья является переводом статьи "
Когда переходишь с одного языка на другой, некоторые вещи лучше было бы не знать вовсе (см.
Вам редко будут нужны счетчики, а итераторы - лишь время от времени
Неправильно:
i = 0
while i
По-питонски:
for i in xrange(10):
do_something(i)
В следующем примере индексируется список.
Неправильно:
i = 0
while i
По-питонски:
for item in lst:
do_something(item)
Переменная-итератор полезна, когда вы хотите сохранить состояние цикла между двумя «прогонами»:
itr_lst = iter(lst)
for item in itr_lst:
do_something(item)
if is_some_condition(item):
break
for item in itr_lst: # продолжает с того места, где завершился
#предыдущий цикл
do_something_else(item)
Цикл for вам, скорее всего, вообще не нужен
Для манипуляций с последовательностями в Python имеется много функциональных возможностей более высокого уровня, таких, как функции zip(), max(), min(), генераторы списков (
Кортежи – это не списки «только для чтения»
Под кортежем обычно подразумевается разнородная коллекция, например, (имя, фамилия) или (ip-адрес, порт). Тип элементов, при этом, может и совпадать (как в кортеже "имя и фамилия" оба элемента могут быть строками), но их значение в реальном мире, как правило, отличается. Кортеж можно представлять себе, как строку в таблице реляционной базы данных – собственно говоря, в формальном определении реляционной модели строка в базе данных кортежем и называется. Напротив, список имен – это всегда список, и даже если некая функция не может этот список изменить, это не делает его кортежем.
Для извлечения значений из кортежа используется полезная техника – распаковка кортежа. Например:
for (ip-адрес, port) in all_connections:
if port
Из этого кода вы видите, что all_connections – это список (или итерируемый объект), содержащий кортежи в форме (ip-адрес, порт). Это гораздо проще, чем использовать for item in all_connections, а затем манипулировать элементами item при помощи item[0] или с использованием других подобных техник.
Распаковка полезна также в случае, когда функция возвращает множественные значения:
name, ext = os.path.splitext(filename) # разбить имя файла на имя
# и расширение
Для группирования служебных функций классы не нужны
В языках C# и Java вы можете поместить код только в пределах классов, что приводит к созданию множества служебных классов, содержащих в себе только статические методы. Типичный пример – математические функции, такие, как sin(). В Python вы в таком случае используете модуль с функциями высшего порядка.
Скажите «нет» геттерам и сеттерам
Да, инкапсуляция очень важна. Нет, «геттеры» и «сеттеры» - не единственный способ реализовать инкапсуляцию. В Python вы можете использовать атрибут
Функции – это объекты
Функция является объектом, который (вот ведь повезло), можно вызвать. В этом примере список словарей сортируется по значению 'price', содержащемуся в словарях:
# определить функцию, возвращающую нужные данные из объекта
def get_price(ob):
return ob['price']
lst.sort(key=get_price) # сортировка списка по значению ['price'],
# содержащемуся в элементах списка
В вышеприведенном примере можно избежать определения простой функции get_price() и, вместо этого, сгенерировать функцию при помощи
А при помощи sorted(lst, key=get_price) можно, вместо того чтобы изменять существующий список, получить новый список.