9.11. Выражения с использованием генераторов

Некоторые простые генераторы могут быть закодированы лаконично как выражения, используя синтаксис, аналогичный списку, но с круглыми скобками вместо квадратных. Эти выражения предназначены для ситуаций, когда генератор используется сразу же, включая функцию. Выражения с генератором более компактные, но менее универсальные, чем полные определения генераторов и, как правило, быть более дружелюбны, чем эквивалентное использование списков.

Примеры:

>>> sum(i*i for i in range(10))                 # sum of squares
285
 
>>> xvec = [10, 20, 30]
>>> yvec = [7, 5, 3]

9.10. Генераторы

Генераторы (docs.python.org/3/glossary.html#term-generator) представляют собой простой и мощный инструмент для создания итераторов. Они написаны как обычные функции, но используют оператор yield (docs.python.org/3/reference/simple_stmts.html#yield), всякий раз когда требуется вернуть данные. Каждый раз next() (docs.python.org/3/library/functions.html#next) вызывается на это, генератор возвращается туда, где был до этого (он запоминает все значения и какой оператор был выполнен последним). Пример показывает, как можно легко создать генератор:

9.9. Итераторы

К этому моменту вы возможно заметили, что большинство контейнерных объектов позволяют совершить по ним циклический проход с помощью оператора for (docs.python.org/3/reference/compound_stmts.html#for):

for element in [1, 2, 3]:
    print(element)
for element in (1, 2, 3):
    print(element)
for key in {'one':1, 'two':2}:
    print(key)
for char in "123":
    print(char)
for line in open("myfile.txt"):
    print(line)

9.8. Исключения - это тоже классы

Определяемые пользователями исключения также идентифицируются классами. Используя этот механизм можно создать расширяемые иерархии исключений.

Существует два новых действительных (семантических) формы для оператора raise (docs.python.org/3/reference/simple_stmts.html#raise):

raise Class
 
raise Instance

В первой форме Class должен быть экземпляром type (docs.python.org/3/library/functions.html#type) или производного от него класса. Первая форма является сокращением для:

raise Class()

9.7. Различные заметки

Иногда бывает полезно иметь тип данных похожий на запись в Паскале или структуру в C, связав вместе несколько именованных элементов данных. Определение пустого класса превосходно представить такую возможность:

class Employee:
    pass
 
john = Employee() # Create an empty employee record
 
# Fill the fields of the record
john.name = 'John Doe'
john.dept = 'computer lab'
john.salary = 1000

9.6. Приватные (Private) переменные

В Python не существует "частных" (приватных) переменных экземпляра, т.е. тех, которые не могут быть доступны, кроме как изнутри объекта. Тем не менее есть соглашение, которое поддерживается большей частью кода Python: идентификатор с префиксом нижней черты (например _spam) должны рассматриваться как непубличная часть API (будь то функция, метод или элемент данных). Следует учитывать, детали реализации и предмет могут быть изменены без предварительного уведомления.

9.5. Наследование (inheritance)

Несомненно особенность языка не имела бы право называться "классом" без поддержки наследования. Синтаксис для определения производного класса выглядит следующим образом:

class DerivedClassName(BaseClassName):
    <statement-1>
    .
    .
    .
    <statement-N>

Имя BaseClassName должны быть определено в пределах области видимости производного класса. На месте имени базового класса, также допускается иные произвольные выражения. Это может быть использовано, например, когда базовый класс определен в другом модуле:
 

Изменение данных файла с помощью модуля shelve

Изменим данный пример "базы данных" так, что объекты будут храниться в файле. Программа должна иметь возможность изменять объекты, хранящиеся в файле.

Модуль shelve позволяет сохранять объекты по ключу. Т.е. чтобы работать с объктом, сохраненным в файле, необходимо указать его ключ. Нет необходимости просматривать содержимое всего файла.

class Subject:
	def __init__(self, s, i, q = 1):
		self.id = i
		self.name = s
		self.qty = q
 
import shelve
f = shelve.open("learning")
l = len(f)

Эмуляция таблицы базы данных с помощью класса и списка

Задача. Создать список объектов. Каждый объект представляет собой как бы запись в таблице базы данных и включает поля: id, название_предмета, количество раз его ввода (qty).

id и qty должны вычисляться автоматически, пользователь вводит только название предмета.
id очередного предмета можно генерировать исходя из количества уже существующих объектов (элементов списка) + 1.

Перед тем, как создавать новый объект, проверяется нет ли уже с таким названием в списке. Если есть, то новый объект не создается, а вызывается метод, меняющий значение поля qty уже существующего объекта.
 

9.4. Некоторые замечания о классах

Атрибуты данных переопределяют атрибуты метода с тем же именем; чтобы избежать случайных конфликтов имен, которые могут привести к трудно обнаруживаемым ошибкам в больших программах, имеет смысл использовать какое-либо соглашение, которое свело бы к минимуму вероятность подобных конфликтов. Это может быть использование большой первой буквы для имен методов, предварение имен атрибутов данных небольшой уникальной строкой (возможно, просто подчеркивание), или использование глаголов для методов и существительных для атрибутов данных.

Syndicate content