Главная страница

справочник по Python. мм isbn 9785932861578 9 785932 861578


Скачать 4.21 Mb.
Названиемм isbn 9785932861578 9 785932 861578
Анкорсправочник по Python
Дата08.05.2022
Размер4.21 Mb.
Формат файлаpdf
Имя файлаBizli_Python-Podrobnyy-spravochnik.440222.pdf
ТипСправочник
#518195
страница3 из 82
1   2   3   4   5   6   7   8   9   ...   82

Hello World


Click here.
‘’’
Строки хранятся как последовательности символов, доступ к которым можно получить с помощью целочисленного индекса, начиная с нуля. Что- бы извлечь из строки единственный символ, можно использовать оператор индексирования s[i], например:

Строки
31
a = “Привет, Мир”
b = a[4] # b = ‘е’
Чтобы извлечь подстроку, можно использовать оператор сечения s[i:j]. Он извлечет из строки s все символы с порядковыми номерами k в диапазоне i
<= k < j
. Если какой-либо из индексов опущен, предполагается, что он со- ответствует началу или концу строки соответственно:
c = a[:6] # c = “Привет”
d = a[8:] # d = “Мир”
e = a[3:9] # e = “вет, М”
Конкатенация строк выполняется с помощью оператора сложения (+):
g = a + “ Это проверка”
Интерпретатор Python никогда не интерпретирует строку как число, даже если она содержит только цифровые символы (как это делается в других языках, таких как Perl или PHP). Например, оператор + всегда выполняет конкатенацию строк:
x = “37”
y = “42”
z = x + y # z = “3742” (конкатенация строк)
Чтобы выполнить арифметическую операцию над значениями, хранящи- мися в виде строк, необходимо сначала преобразовать строки в числовые значения с помощью функции int() или float(). Например:
z = int(x) + int(y) # z = 79 (целочисленное сложение)
Нестроковые значения можно преобразовать в строковое представление с помощью функции str(), repr() или format(). Например:
s = “Значение переменной x: “ + str(x)
s = “Значение переменной x: “ + repr(x)
s = “Значение переменной x: “ + format(x,”4d”)
Несмотря на то что обе функции str() и repr() воспроизводят строки, на самом деле возвращаемые ими результаты обычно немного отличаются.
Функция str() воспроизводит результат, который дает применение ин- струкции print, тогда как функция repr() воспроизводит строку в том виде, в каком она обычно вводится в тексте программы для точного представле- ния значения объекта. Например:
>>> x = 3.4
>>> str(x)
‘3.4’
>>> repr(x)
‘3.3999999999999999’
>>>
Ошибка округления числа 3.4 в предыдущем примере не является ошиб- кой Python. Это следствие особенностей представления чисел с плавающей точкой двойной точности, которые не могут быть точно представлены в де- сятичном формате из-за аппаратных ограничений компьютера.

32
Глава 1. Вводное руководство
Для преобразования значений в строку с возможностью форматирования используется функция format(). Например:
>>> format(x,”0.5f”)
‘3.40000’
>>>
Списки
Списки
– это последовательности произвольных объектов. Списки созда- ются посредством заключения элементов списка в квадратные скобки, как показано ниже:
names = [ “Dave”, “Mark”, “Ann”, “Phil” ]
Элементы списка индексируются целыми числами, первый элемент списка имеет индекс, равный нулю. Для доступа к отдельным элементам списка используется оператор индексирования:
a = names[2] # Вернет третий элемент списка, “Ann”
names[0] = “Jeff” # Запишет имя “Jeff” в первый элемент списка
Для добавления новых элементов в конец списка используется метод ap- pend()
:
names.append(“Paula”)
Для вставки элемента в середину списка используется метод insert():
names.insert(2, “Thomas”)
С помощью оператора среза можно извлекать и изменять целые фрагменты списков:
b = names[0:2] # Вернет [“Jeff”,
“Mark”]
c = names[2:] # Вернет [“Thomas”,
“Ann”,“Phil”,“Paula”]
names[1] = ‘Jeff’ # Во второй элемент запишет имя ‘Jeff’
names[0:2] = [‘Dave’,’Mark’,’Jeff’] # Заменит первые два элемента
# списком справа.
Оператор сложения (+) выполняет конкатенацию списков:
a = [1,2,3] + [4,5] # Создаст список [1,2,3,4,5]
Пустой список можно создать одним из двух способов:
names = [] # Пустой список names = list() # Пустой список
Список может содержать объекты любого типа, включая другие списки, как показано в следующем примере:
a = [1,”Dave”,3.14, [“Mark”, 7, 9, [100,101]], 10]
Доступ к элементам во вложенных списках осуществляется с применени- ем дополнительных операторов индексирования, как показано ниже:

Кортежи
33
a[1] # Вернет “Dave”
a[3][2] # Вернет 9
a[3][3][1] # Вернет 101
Программа в листинге 1.2 демонстрирует дополнительные особенности списков. Она читает список чисел из файла, имя которого указывается в виде аргумента командной строки, и выводит минимальное и макси- мальное значения.
Листинг 1.2. Дополнительные особенности списков
import sys # Загружает модуль sys if len(sys.argv) != 2 : # Проверка количества аргументов командной строки:
print “Пожалуйста, укажите имя файла”
raise SystemExit(1)
f = open(sys.argv[1]) # Имя файла, полученное из командной строки lines = f.readlines() # Читает все строки из файла в список f.close()
ёё
# Преобразовать все значения из строк в числа с плавающей точкой fvalues = [float(line) for line in lines]
ёё
# Вывести минимальное и максимальное значения print “Минимальное значение: “, min(fvalues)
print “Максимальное значение: “, max(fvalues)
В первой строке этой программы с помощью инструкции import загружает- ся модуль sys из стандартной библиотеки Python. Этот модуль использует-
Python. Этот модуль использует-
. Этот модуль использует- ся для получения доступа к аргументам командной строки.
Функции open() передается имя файла, которое было получено как аргу- мент командной строки и помещено в список sys.argv. Метод readlines() чи- тает все строки из файла и возвращает список строк.
Выражение [float(line) for line in lines] создает новый список, выпол- няя обход всех строк и применяя функцию float() к каждой из них. Эта конструкция, чрезвычайно удобная для создания списков, называется ге-
нератором списков
. Поскольку строки из файла можно также читать с по- мощью цикла for, программу можно сократить, объединив чтение файла и преобразование значений в одну инструкцию, как показано ниже:
fvalues = [float(line) for line in open(sys.argv[1])]
После того как входные строки будут преобразованы в список, содержа- щий числа с плавающей точкой, с помощью встроенных функций min() и max() отыскиваются минимальное и максимальное значения.
Кортежи
Для создания простейших структур данных можно использовать корте-
жи
, которые позволяют упаковывать коллекции значений в единый объ- ект. Кортеж создается заключением группы значений в круглые скобки, например:
stock = (‘GOOG’, 100, 490.10)

34
Глава 1. Вводное руководство address = (‘www.python.org’, 80)
person = (first_name, last_name, phone)
Интерпретатор Python часто распознает кортежи, даже если они не заклю-
Python часто распознает кортежи, даже если они не заклю- часто распознает кортежи, даже если они не заклю- чены в круглые скобки:
stock = ‘GOOG’, 100, 490.10
address = ‘www.python.org’,80
person = first_name, last_name, phone
Для полноты можно отметить, что имеется возможность определять кор- тежи, содержащие 0 или 1 элемент, для чего используется специальный синтаксис:
a = () # Кортеж с нулевым количеством элементов (пустой кортеж)
b = (item,) # Кортеж с одним элементом (обратите внимание на запятую в конце)
c = item, # Кортеж с одним элементом (обратите внимание на запятую в конце)
Элементы кортежа могут извлекаться с помощью целочисленных индек- сов, как и в случае со списками. Однако более часто используется прием распаковывания кортежей во множество переменных, как показано ниже:
name, shares, price = stock host, port = address first_name, last_name, phone = person
Кортежи поддерживают практически те же операции, что и списки (такие как доступ к элементам по индексу, извлечение среза и конкатенация), тем не менее содержимое кортежа после его создания невозможно изменить (то есть нельзя изменить, удалить или добавить новый элемент в существую- щий кортеж). По этой причине кортеж лучше рассматривать как единый объект, состоящий из нескольких частей, а не как коллекцию отдельных объектов, в которую можно вставлять новые или удалять существующие элементы.
Вследствие большого сходства кортежей и списков некоторые программи- сты склонны полностью игнорировать кортежи и использовать списки, по- тому что они выглядят более гибкими. Хотя в значительной степени это так и есть, тем не менее, если в программе создается множество небольших списков (когда каждый содержит не более десятка элементов), то они за- нимают больший объем памяти, по сравнению с кортежами. Это обуслов- лено тем, что для хранения списков выделяется немного больше памяти, чем требуется, – с целью оптимизировать скорость выполнения операций, реализующих добавление новых элементов. Так как кортежи доступны только для чтения, для их хранения используется меньше памяти, т. к. до- полнительное пространство не выделяется.
Кортежи и списки часто используются совместно. Например, следующая программа демонстрирует, как можно организовать чтение данных из фай- ла с переменным количеством столбцов, где значения отделяются друг от друга запятыми:
# Файл содержит строки вида “name,shares,price”
filename = “portfolio.csv”
portfolio = []

Множества
35
for line in open(filename):
fields = line.split(“,”) # Преобразует строкувсписок name = fields[0] # Извлекает ипреобразуетотдельныезначенияполей shares = int(fields[1])
price = float(fields[2])
stock = (name,shares,price) # Создает кортеж(name,shares,price)
portfolio.append(stock) # Добавляет всписокзаписей
Строковый метод split() разбивает строку по указанному символу и соз- дает список значений. Структура данных portfolio, созданная этой про- граммой, имеет вид двухмерного массива строк и столбцов. Каждая строка представлена кортежем и может быть извлечена, как показано ниже:
>>> portfolio[0]
(‘GOOG’, 100, 490.10)
>>> portfolio[1]
(‘MSFT’, 50, 54.23)
>>>
Отдельные значения могут извлекаться следующим способом:
>>> portfolio[1][1]
50
>>> portfolio[1][2]
54.23
>>>
Ниже приводится простейший способ реализовать обход всех записей и распаковать значения полей в набор переменных:
total = 0.0
for name, shares, price in portfolio:
total += shares * price
Множества
Множества
используются для хранения неупорядоченных коллекций объектов. Создаются множества с помощью функции set(), которой пере- даются последовательности элементов, как показано ниже:
s = set([3,5,9,10]) # Создаст множество чисел t = set(“Hello”) # Создаст множество уникальных символов
В отличие от кортежей, множества являются неупорядоченными коллек- циями и не предусматривают возможность доступа к элементам по число- вому индексу. Более того, элементы множества никогда не повторяются.
Например, если поближе рассмотреть значения, полученные в предыду- щем примере, можно заметить следующее:
>>> t
set([‘H’, ‘e’, ‘l’, ‘o’])
Обратите внимание, что в множестве присутствует только один символ ‘l’.

36
Глава 1. Вводное руководство
М
ножества поддерживают стандартные операции над коллекциями, включая объединение, пересечение, разность и симметричную разность.
Например:
a = t | s # Объединение t и s b = t & s # Пересечение t и s c = t – s # Разность (элементы, присутствующие в t, но отсутствующие в s)
d = t ^ s # Симметричная разность (элементы, присутствующие в t или в s,
# но не в двух множествах сразу)
С помощью методов add() и update() можно добавлять новые элементы в множество:
t.add(‘x’) # Добавит единственный элемент s.update([10,37,42]) # Добавит несколько элементов в множество s
Удалить элемент множества можно с помощью метода remove():
t.remove(‘H’)
Словари
Словарь
– это ассоциативный массив, или таблица хешей, содержащий объекты, индексированные ключами. Чтобы создать словарь, последова- тельность элементов необходимо заключить в фигурные скобки ({}), как показано ниже:
stock = {
“name” : “GOOG”,
“shares” : 100,
“price” : 490.10
}
Доступ к элементам словаря осуществляется с помощью оператора индек- сирования по ключу:
name = stock[“name”]
value = stock[“shares”] * stock[“price”]
Добавление или изменение объектов в словаре выполняется следующим способом:
stock[“shares”] = 75
stock[“date”] = “June 7, 2007”
Чаще всего в качестве ключей применяются строки, тем не менее, для этих целей допускается использовать большинство других объектов языка Py-
Py- thon, включая числа и кортежи. Определенные объекты, включая списки и словари, не могут использоваться в качестве ключей, потому что их со- держимое может изменяться.
Словари обеспечивают удобный способ определения объектов, содержащих именованные поля, как было показано выше. Кроме того, словари могут использоваться, как контейнеры, позволяющие быстро выполнять поиск в неупорядоченных данных. В качестве примера ниже приводится словарь, содержащий цены на акции:

Итерации и циклы
37
prices = {
“GOOG” : 490.10,
“AAPL” : 123.50,
“IBM” : 91.50,
“MSFT” : 52.13
}
Создать пустой словарь можно одним из двух способов:
prices = {} # Пустой словарь prices = dict() # Пустой словарь
Проверку наличия элемента в словаре можно выполнить с помощью опера- тора in, как показано в следующем примере:
if “SCOX” in prices:
p = prices[“SCOX”]
else:
p = 0.0
Данную последовательность действий можно выразить в более компактной форме:
p = prices.get(“SCOX”,0.0)
Чтобы получить список ключей словаря, словарь можно преобразовать в список:
syms = list(prices) # syms = [“AAPL”, “MSFT”, “IBM”, “GOOG”]
Для удаления элементов словаря используется инструкция del:
del prices[“MSFT”]
Словари являются, пожалуй, наиболее оптимизированным типом данных в языке Python. Поэтому если в программе необходимо организовать хра- нение и обработку данных, практически всегда лучше использовать слова- ри, а не пытаться создавать собственные структуры данных.
Итерации и циклы
Для организации циклов наиболее часто используется инструкция for, ко- торая позволяет выполнить обход элементов коллекции. Итерации – одна из самых богатых особенностей языка Python. Однако наиболее часто ис-
Python. Однако наиболее часто ис-
. Однако наиболее часто ис- пользуемой формой итераций является простой цикл по элементам после- довательности, такой как строка, список или кортеж. Пример реализации итераций приводится ниже:
for n in [1,2,3,4,5,6,7,8,9]:
print “2 в степени %d = %d” % (n, 2**n)
В данном примере на каждой итерации переменная n будет последователь- но получать значения из списка [1,2,3,4,…,9]. Поскольку необходимость ор- ганизовать цикл по фиксированному диапазону целочисленных значений возникает достаточно часто, для этих целей используется сокращенная форма записи:

38
Глава 1. Вводное руководство for n in range(1,10):
print “2 в степени %d = %d” % (n, 2**n)
Ф
ункция range(i,j [,stride]) создает объект, представляющий диапазон це- лых чисел со значениями от i по j-1. Если начальное значение не указано, оно берется равным нулю. В третьем необязательном аргументе stride мож- но передать шаг изменения значений. Например:
a = range(5) # a = 0,1,2,3,4
b = range(1,8) # b = 1,2,3,4,5,6,7
c = range(0,14,3) # c = 0,3,6,9,12
d = range(8,1,-1) # d = 8,7,6,5,4,3,2
Будьте внимательны при использовании функции range() в Python 2, так как в этой версии интерпретатора она создает полный список значений.
Для очень больших диапазонов это может привести к ошибке нехватки па- мяти. Поэтому при работе с ранними версиями Python программисты ис-
Python программисты ис- программисты ис- пользуют альтернативную функцию xrange(). Например:
for i in xrange(100000000): # i = 0,1,2,...,99999999
инструкции
Функция xrange() создает объект, который вычисляет очередное значение только в момент обращения к нему. Именно поэтому данный способ явля- ется более предпочтительным при работе с большими диапазонами целых чисел. В версии Python 3 функция xrange() была переименована в range(), а прежняя реализация функции range() была удалена.
Возможности инструкции for не ограничиваются последовательностями целых чисел, она также может использоваться для реализации итераций через объекты самых разных типов, включая строки, списки, словари и файлы. Например:
a = “Привет, Мир”
# Вывести отдельные символы в строке a for c in a:
print c
ёё
b = [“Dave”,”Mark”,”Ann”,”Phil”]
# Вывести элементы списка for name in b:
print name
ёё
c = { ‘GOOG’ : 490.10, ‘IBM’ : 91.50, ‘AAPL’ : 123.15 }
# Вывести элементы словаря for key in c:
print key, c[key]
ёё
# Вывести все строки из файла f = open(“foo.txt”)
for line in f:
print line,
Цикл for является одной из самых мощных особенностей языка Python, так как позволяет вам создавать собственные объекты-итераторы и функции- генераторы, которые возвращают последовательности значений. Подроб-

Функции
39
нее об итераторах и генераторах рассказывается в следующей главе, а так- же в главе 6 «Функции и функциональное программирование».
Функции
Создание функции производится с помощью инструкции def, как показано в следующем примере:
def remainder(a, b):
q = a // b # // – оператор деления с усечением дробной части.
r = a - q*b return r
Чтобы вызвать функцию, достаточно указать ее имя и следующий за ним список аргументов, заключенный в круглые скобки, например: result = re-
= re- re- mainder(37, 15)
. Если потребуется вернуть из функции несколько значений, можно использовать кортеж, как показано ниже:
def divide(a, b):
q = a // b # Если a и b – целые числа, q будет целым числом r = a - q*b return (q,r)
Когда функция возвращает кортеж с несколькими значениями, его лег- ко можно распаковать в множество отдельных переменных, как показано ниже:
quotient, remainder = divide(1456, 33)
Присвоить аргументу функции значение по умолчанию можно с помощью оператора присваивания:
def connect(hostname, port, timeout=300):
# Тело функции
Если в определении функции для каких-либо параметров указаны значе- ния по умолчанию, при последующих вызовах функции эти параметры можно опустить. Если при вызове какой-то из этих параметров не указан, он получает значение по умолчанию. Например:
connect(‘www.python.org’, 80)
Также имеется возможность передавать функции именованные аргумен- ты, которые при этом можно перечислять в произвольном порядке. Однако в этом случае вы должны знать, какие имена аргументов указаны в опреде- лении функции. Например:
connect(port=80, hostname=”www.python.org”)
Когда внутри функции создаются новые переменные, они имеют локаль- ную область видимости. То есть такие переменные определены только в пределах тела функции, и они уничтожаются, когда функция возвра- щает управление вызывающей программе. Чтобы иметь возможность из- менять глобальные переменные внутри функции, эти переменные следует определить в теле функции с помощью инструкции global:

40
Глава 1. Вводное руководство count = 0
...
def foo():
global count count += 1 # Изменяет значение глобальной переменной count
Генераторы
Вместо единственного значения функция, с помощью инструкции yield, может генерировать целые последовательности результатов. Например:
def countdown(n):
print “Обратный отсчет!”
while n > 0:
yield n # Генерирует значение (n)
n -= 1
Любая функция, которая использует инструкцию yield, называется гене-
ратором
. При вызове функции-генератора создается объект, который по- зволяет получить последовательность результатов вызовом метода next()
(или __next__() в Python 3). Например:
>>> c = countdown(5)
>>> c.next()
Обратный отсчет!
5
>>> c.next()
4
>>> c.next()
3
>>>
Метод next() заставляет функцию-генератор выполняться, пока не будет достигнута следующая инструкция yield. После этого метод next() воз- вращает значение, переданное инструкции yield, и выполнение функции приостанавливается. При следующем вызове метода next() функция про- должит выполнение, начиная с инструкции, следующей непосредственно за инструкцией yield. Этот процесс продолжается, пока функция не вернет управление.
Как правило, метод next() не вызывается вручную, как это было показано выше. Вместо этого функция-генератор обычно используется в инструк- ции цикла for, например:
>>> for i in countdown(5):
...
print i,
Обратный отсчет!
5 4 3 2 1
>>>
Генераторы обеспечивают чрезвычайно широкие возможности при конвей- ерной обработке или при работе с потоками данных. Например, следую- щая функция-генератор имитирует поведение команды tail -f, которая ча-

Сопрограммы
41
сто используется в операционной системе UNIX для мониторинга файлов журналов:
# следит за содержимым файла (на манер команды tail -f)
import time def tail(f):
f.seek(0,2) # Переход в конец файла while True:
line = f.readline() # Попытаться прочитать новую строку текста if not line: # Если ничего не прочитано, time.sleep(0.1) # приостановиться на короткое время continue # и повторить попытку yield line
Ниже приводится пример генератора, который отыскивает определенную подстроку в последовательности строк:
def grep(lines, searchtext):
for line in lines:
if searchtext in line: yield line
Ниже приводится пример, в котором объединены оба эти генератора с це- лью реализовать простейшую конвейерную обработку:
# Реализация последовательности команд “tail -f | grep python”
# на языке Python wwwlog = tail(open(“access-log”))
pylines = grep(wwwlog,”python”)
for line in pylines:
print line,
Одна из важных особенностей генераторов состоит в том, что они могут ис- пользоваться вместо других итерируемых объектов, таких как списки или файлы. В частности, когда вы пишете такую инструкцию, как for item in s, имя s может представлять список элементов, строки в файле, результат вы- зова функции-генератора или любой другой объект, поддерживающий ите- рации. Возможность использования самых разных объектов под именем s может оказаться весьма мощным инструментом создания расширяемых программ.
Сопрограммы
Обычно функции оперируют единственным набором входных аргумен- тов. Однако функцию можно написать так, что она будет действовать, как программа, обрабатывающая последовательность входных данных.
Такие функции называются сопрограммами, а создаются они с помощью инструкции yield, используемой в выражении (yield), как показано в сле- дующем примере:
def print_matches(matchtext):
print “Поиск подстроки”, matchtext while True:
line = (yield) # Получение текстовой строки

42
Глава 1. Вводное руководство if matchtext in line:
print line
Чтобы воспользоваться описанной функцией, сначала необходимо вы- звать ее, затем добиться перемещения потока выполнения до первой ин- струкции (yield), а потом начать передачу данных с помощью метода send()
. Например:
>>> matcher = print_matches(“python”)
>>> matcher.next() # Перемещение до первой инструкции (yield)
Поиск подстроки python
>>> matcher.send(“Hello World”)
>>> matcher.send(“python is cool”)
python is cool
>>> matcher.send(“yow!”)
>>> matcher.close() # Завершение работы с объектом matcher
>>>
Выполнение сопрограммы приостанавливается до тех пор, пока ей не будет передано новое значение с помощью метода send(). Когда это произойдет, выражение (yield) внутри сопрограммы вернет полученное значение и ее работа продолжится со следующей инструкции. Сопрограмма будет вы- полняться, пока не будет встречено следующее выражение (yield) – в этой точке выполнение функции будет приостановлено. Этот процесс будет про- должаться, пока либо сопрограмма сама не вернет управление, либо пока не будет вызван метод close(), как было показано в предыдущем примере.
Сопрограммы удобно использовать при разработке многозадачных про- грамм, работа которых укладывается в схему «производитель-потреби- тель», когда одна часть программы производит некоторые данные, а другая часть потребляет их. В этой схеме сопрограммам отводится роль «потреби- теля» данных. Ниже приводится пример программы, в которой совместно действуют генератор и сопрограмма:
# Множество сопрограмм поиска matchers = [
print_matches(“python”),
print_matches(“guido”),
print_matches(“jython”)
]
ёё
# Подготовка всех подпрограмм к последующему вызову метода next()
for m in matchers: m.next()
ёё
# Передать активный файл журнала всем сопрограммам.
# Обратите внимание: для нормальной работы необходимо,
# чтобы веб-сервер активно записывал данные в журнал.
wwwlog = tail(open(“access-log”))
for line in wwwlog:
for m in matchers:
m.send(line) # Передача данных каждой из сопрограмм
Дополнительная информация о сопрограммах приводится в главе 6.

Объекты и классы
43
Объекты и классы
Все значения, используемые программами, являются объектами. Объект содержит некоторые внутренние данные и обладает методами, позволяю- щими выполнять различные операции над этими данными. Вам уже при- ходилось использовать объекты и методы, когда вы работали с данными встроенных типов, такими как строки и списки. Например:
items = [37, 42] # Создание списка объектов items.append(73) # Вызов метода append()
Функция dir() выводит список всех методов объекта и является удобным инструментом для проведения экспериментов в интерактивной оболочке.
Например:
>>> items = [37, 42]
>>> dir(items)
[‘__add__’, ‘__class__’, ‘__contains__’, ‘__delattr__’, ‘__delitem__’,
...
‘append’, ‘count’, ‘extend’, ‘index’, ‘insert’, ‘pop’,
‘remove’, ‘reverse’, ‘sort’]
>>>
При исследовании объектов можно заметить уже знакомые методы, такие как append() и insert(). Кроме того, в списках можно также увидеть специ- альные методы, имена которых всегда начинаются и заканчиваются двумя символами подчеркивания. Эти методы реализуют различные операторы языка. Например, метод __add__() реализует оператор +:
>>> items.__add__([73,101])
[37, 42, 73, 101]
>>>
Для определения новых типов объектов и в объектно-ориентированном программировании используется инструкция class. Например, ниже при- водится определение простого класса стека, обладающего методами push(), pop()
и length():
class Stack(object):
def __init__(self): # Инициализация стека self.stack = [ ]
def push(self,object):
self.stack.append(object)
def pop(self):
return self.stack.pop()
def length(self):
return len(self.stack)
В первой строке определения класса инструкция class Stack(object) объяв- ляет, что Stack – это объект. В круглых скобках указывается, наследником какого класса является объявляемый класс; в данном случае класс Stack наследует свойства и методы класса object, который является родоначаль- ником всех типов данных в языке Python. Внутри объявления класса опре-
Python. Внутри объявления класса опре-
. Внутри объявления класса опре- деляются методы, с помощью инструкции def. Первый аргумент любого ме-

44
Глава 1. Вводное руководство тода всегда ссылается на сам объект. В соответствии с соглашениями этому аргументу обычно дается имя self. Все методы, выполняющие операции над атрибутами объекта, должны явно ссылаться на переменную self. Методы, имена которых начинаются и заканчиваются двумя символами подчерки- вания, являются специальными методами. Например, метод __init__() ис- пользуется для инициализации объекта после его создания.
Ниже приводится пример использования класса:
s = Stack() # Создать стек s.push(“Dave”) # Поместить на стек некоторые данные s.push(42)
s.push([3,4,5])
x = s.pop() # переменная x получит значение [3,4,5]
y = s.pop() # переменная y получит значение 42
del s # Уничтожить объект s
В этом примере был создан совершенно новый объект, реализующий стек.
Однако по своей природе стек очень похож на встроенный тип списка. По- этому можно было бы унаследовать класс list и добавить один дополни- тельный метод:
class Stack(list):
# Добавить метод push() интерфейса стека
# Обратите внимание: списки уже имеют метод pop().
def push(self,object):
self.append(object)
Обычно все методы, присутствующие в объявлении класса, могут приме- няться только к экземплярам данного класса (то есть к созданным объ- ектам). Однако существует возможность определять методы различных видов, например статические, знакомые программистам по языкам C++ и Java:
class EventHandler(object):
@staticmethod def dispatcherThread():
while (1):
# Ожидание запроса
...
ёё
EventHandler.dispatcherThread() # Вызов метода как обычной функции
В данном случае @staticmethod объявляет следующий за ним метод стати- ческим. @staticmethod – это пример использования декоратора, подробнее о которых будет рассказываться в главе 6.
Исключения
При возникновении ошибки в программе возбуждается исключение и вы- водится трассировочная информация, такая, как показано ниже:
Traceback (most recent call last):
File “foo.py”, line 12, in
IOError: [Errno 2] No such file or directory: ‘file.txt’

Исключения
45
(Перевод:
Трассировочная информация (самый последний вызов – самый нижний):
Файл “foo.py”, строка 12, в <модуль>
IOError: [Errno 2] Нет такого файла или каталога: ‘file.txt’
)
Т
рассировочная информация позволяет определить тип ошибки и место, где она возникла. Обычно ошибки приводят к аварийному завершению программы. Однако имеется возможность перехватить и обработать ис- ключение – с помощью инструкций try и except, как показано ниже:
try:
f = open(“file.txt”,”r”)
except IOError as e:
print e
Если будет возбуждено исключение IOError, информация о причинах по- явления ошибки будет записана в переменную e и управление будет пере- дано первой инструкции в блоке except. Если возникнет какое-то другое исключение, оно будет передано объемлющему блоку кода (если таковой имеется). Если операция выполнена без ошибок, инструкции в блоке except будут просто игнорироваться. После обработки исключения выполнение программы продолжится с первой инструкции, следующей за последней инструкцией в блоке except. Программа не возвращается в то место, где воз- никло исключение.
Возбудить исключение вручную можно с помощью инструкции raise. Для этого инструкции raise можно передать один из встроенных классов ис- ключений, например:
raise RuntimeError(“Компьютер говорит нет”)
Или создать и использовать собственный класс исключения, как описано в разделе «Определение новых исключений» в главе 5 «Структура програм- мы и управление потоком выполнения».
Управление системными ресурсами, такими как блокировки, файлы и се- тевые соединения, часто является достаточно сложным делом, особенно когда при этом необходимо предусматривать обработку исключений. Упро- стить решение таких задач программирования можно с помощью инструк- ции with, применяя ее к объектам определенного типа. Ниже приводится пример программного кода, который использует мьютекс в качестве бло- кировки:
import threading message_lock = threading.Lock()
...
with message_lock:
messages.add(newmessage)
В этом примере при выполнении инструкции with автоматически приобре- тается объект блокировки message_lock. Когда поток выполнения покидает контекст блока with, блокировка автоматически освобождается. Благодаря этому обеспечивается надежное управление блокировкой, независимо от того, что происходит внутри блока with. Например, даже если при выпол-

46
Глава 1. Вводное руководство нении инструкций внутри блока возникнет исключение, блокировка все равно будет освобождена после выхода за его пределы.
Обычно инструкция with совместима только с объектами, представляю- щими те или иные системные ресурсы или среду выполнения, такие как файлы, соединения и блокировки. Однако имеется возможность реализо- вать поддержку этой инструкции в своих классах. Подробнее об этом рас- сказывается в разделе «Протокол управления контекстом» главы 3 «Типы данных и объекты».
Модули
Часто по мере роста программы возникает желание разбить ее на несколь- ко файлов, чтобы упростить ее разработку и дальнейшее сопровождение.
Язык Python позволяет помещать определения в файлы и использовать их как модули, которые могут импортироваться другими программами и сце- нариями. Чтобы создать модуль, необходимо поместить соответствующие инструкции и определения в файл с тем же именем, которое будет присвое- но модулю. (Обратите внимание, что имя файла должно иметь расширение
.py
.) Например:
# файл : div.py def divide(a, b):
q = a/b # Если a и b – целые числа, q будет целым числом r = a - q*b return (q, r)
Использовать модуль в других программах можно с помощью инструкции import
:
import div a, b = div.divide(2305, 29)
Инструкция import создает новое пространство имен и внутри этого про- странства имен выполняет все инструкции, находящиеся в файле с рас- ширением .py. Чтобы получить доступ к содержимому этого пространства имен после импортирования, достаточно просто использовать имя моду- ля в качестве префикса, как это сделано в вызове функции div.divide() в преды дущем примере.
Если потребуется импортировать модуль под другим именем, достаточно добавить в инструкцию import дополнительный квалификатор as, как по- казано ниже:
import div as foo a,b = foo.divide(2305,29)
Чтобы импортировать некоторые определения в текущее пространство имен, можно воспользоваться инструкцией from:
from div import divide a,b = divide(2305,29) # Префикс div больше не нужен
Чтобы загрузить в текущее пространство имен все содержимое модуля, можно использовать следующий прием:

Получение справки
47
from div import *
При вызове функции dir() с именем модуля она выведет содержимое ука- занного модуля, что делает эту фунцию удобным инструментом для экспе- риментов в интерактивной оболочке:
>>> import string
>>> dir(string)
[‘__builtins__’, ‘__doc__’, ‘__file__’, ‘__name__’, ‘_idmap’,
‘_idmapL’, ‘_lower’, ‘_swapcase’, ‘_upper’, ‘atof’, ‘atof_error’,
‘atoi’, ‘atoi_error’, ‘atol’, ‘atol_error’, ‘capitalize’,
‘capwords’, ‘center’, ‘count’, ‘digits’, ‘expandtabs’, ‘find’,
...
>>>
Получение справки
При работе с интерпретатором Python у вас всегда под рукой будет несколь-
Python у вас всегда под рукой будет несколь- у вас всегда под рукой будет несколь- ко источников справочной информации. Во-первых, при работе в интерак- тивном режиме с помощью команды help() можно получить информацию о любом встроенном модуле и о других аспектах языка Python. Можно про-
Python. Можно про-
. Можно про- сто ввести команду help() и получить общую справочную информацию или команду help(‘имя_модуля’), чтобы получить информацию о конкретном мо- дуле. Если команде help() передать имя определенной функции, она может вернуть информацию об этой функции.
Большинство функций в языке Python снабжены строками документиро-
Python снабжены строками документиро- снабжены строками документиро- вания, описывающими порядок их использования. Чтобы вывести стро- ку документирования, достаточно просто вывести содержимое атрибута
__doc__
. Например:
>>> print issubclass.__doc__
issubclass(C, B) -> bool
ёё
Return whether class C is a subclass (i.e., a derived class) of class B.
When using a tuple as the second argument issubclass(X, (A, B, ...)),
is a shortcut for issubclass(X, A) or issubclass(X, B) or ... (etc.).
(Перевод
Проверяет, является ли класс C подклассом (то есть наследует) класса B.
Когда во втором аргументе передается кортеж – issubclass(X, (A, B, ...)),
такой вызов является сокращенным вариантом issubclass(X, A) or issubclass(X, B) or ... (и т. д.).
)
>>>
И последнее, но также важное замечание – большинство инсталляций Py-
Py- thon включает также команду pydoc, которая может использоваться для получения документации о модулях Python. Для этого достаточно просто ввести команду pydoc topic в системной командной строке.

1   2   3   4   5   6   7   8   9   ...   82


написать администратору сайта