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

Самоучитель PythonВыпуск 2Дмитрий Мусинмая 07, 2017


Скачать 0.74 Mb.
НазваниеСамоучитель PythonВыпуск 2Дмитрий Мусинмая 07, 2017
Дата20.01.2019
Размер0.74 Mb.
Формат файлаpdf
Имя файлаPython3.pdf
ТипПрограмма
#64480
страница9 из 12
1   ...   4   5   6   7   8   9   10   11   12

Подключение модуля из стандартной библиотеки
Подключить модуль можно с помощью инструкции import. К примеру, подключим мо- дуль os для получения текущей директории:
>>>
import os
>>>
os getcwd()
'C:\\Python33'
После ключевого слова import указывается название модуля. Одной инструкцией можно подключить несколько модулей, хотя этого не рекомендуется делать, так как это снижает читаемость кода. Импортируем модули time и
random
>>>
import time
,
random
>>>
time time()
1376047104.056417
>>>
random random()
0.9874550833306869
105

Самоучитель Python, Выпуск 0.2
После импортирования модуля его название становится переменной, через которую можно получить доступ к атрибутам модуля. Например, можно обратиться к константе e, расположенной в модуле math
:
>>>
import math
>>>
math e
2.718281828459045
Стоит отметить, что если указанный атрибут модуля не будет найден, возбудится ис- ключение
AttributeError. А если не удастся найти модуль для импортирования, то
ImportError.
>>>
import notexist
Traceback (most recent call last):
File "", line 1, in import notexist
ImportError
: No module named 'notexist'
>>>
import math
>>>
math
Ё
Traceback (most recent call last):
File "", line 1, in math.Ё
AttributeError
: 'module' object has no attribute 'Ё'
Использование псевдонимов
Если название модуля слишком длинное, или оно вам не нравится по каким-то другим причинам, то для него можно создать псевдоним, с помощью ключевого слова as.
>>>
import math as m
>>>
m e
2.718281828459045
Теперь доступ ко всем атрибутам модуля math осуществляется только с помощью пере- менной m, а переменной math в этой программе уже не будет (если, конечно, вы после этого не напишете import math, тогда модуль будет доступен как под именем m, так и под именем math).
Инструкция from
Подключить определенные атрибуты модуля можно с помощью инструкции from. Она имеет несколько форматов:
from
<
Название модуля
>
import
<
Атрибут
1
>
[
as
<
Псевдоним
1
>
], [
<
Атрибут
2
>
[
as
˓→
<
Псевдоним
2
>
]
]
from
<
Название модуля
>
import
*
27.2. Использование псевдонимов
106

Самоучитель Python, Выпуск 0.2
Первый формат позволяет подключить из модуля только указанные вами атрибуты. Для длинных имен также можно назначить псевдоним, указав его после ключевого слова as.
>>>
from math import e, ceil as c
>>>
e
2.718281828459045
>>>
c(
4.6
)
5
Импортируемые атрибуты можно разместить на нескольких строках, если их много, для лучшей читаемости кода:
>>>
from math import
(sin, cos,
tan, atan)
Второй формат инструкции from позволяет подключить все (точнее, почти все) перемен- ные из модуля. Для примера импортируем все атрибуты из модуля sys
:
>>>
from sys import
*
>>>
version
'3.3.2 (v3.3.2:d047928ae3f6, May 16 2013, 00:03:43) [MSC v.1600 32 bit (Intel)]'
>>>
version_info sys.version_info(major=3, minor=3, micro=2, releaselevel='final', serial=0)
Следует заметить, что не все атрибуты будут импортированы. Если в модуле определена переменная __all__ (список атрибутов, которые могут быть подключены), то будут под- ключены только атрибуты из этого списка. Если переменная __all__ не определена, то бу- дут подключены все атрибуты, не начинающиеся с нижнего подчёркивания. Кроме того,
необходимо учитывать, что импортирование всех атрибутов из модуля может нарушить пространство имен главной программы, так как переменные, имеющие одинаковые име- на, будут перезаписаны.
Создание своего модуля на Python
Теперь пришло время создать свой модуль. Создадим файл mymodule.py, в которой опре- делим какие-нибудь функции:
def hello
():
print
(
'Hello, world!'
)
def fib
(n):
a
=
b
=
1
for i
in range
(n
-
2
):
a, b
=
b, a
+
b return b
Теперь в этой же папке создадим другой файл, например, main.py:
27.4. Создание своего модуля на Python
107

Самоучитель Python, Выпуск 0.2
import mymodule mymodule hello()
print
(mymodule fib(
10
))
Выведет:
Hello, world!
55
Поздравляю! Вы сделали свой модуль! Напоследок отвечу ещё на пару вопросов, связан- ных с созданием модулей:
Как назвать модуль?
Помните, что вы (или другие люди) будут его импортировать и использовать в качестве переменной. Модуль нельзя именовать также, как и ключевое слово (их список можно посмотреть тут
). Также имена модулей нельзя начинать с цифры. И не стоит называть модуль также, как какую-либо из встроенных функций
. То есть, конечно, можно, но это создаст большие неудобства при его последующем использовании.
Куда поместить модуль?
Туда, где его потом можно будет найти. Пути поиска модулей указаны в переменной sys.path. В него включены текущая директория (то есть модуль можно оставить в пап- ке с основной программой), а также директории, в которых установлен python. Кроме того, переменную sys.path можно изменять вручную, что позволяет положить модуль в любое удобное для вас место (главное, не забыть в главной программе модифицировать sys.path).
Можно ли использовать модуль как самостоятельную программу?
Можно. Однако надо помнить, что при импортировании модуля его код выполняется полностью, то есть, если программа что-то печатает, то при её импортировании это будет напечатано. Этого можно избежать, если проверять, запущен ли скрипт как программа,
или импортирован. Это можно сделать с помощью переменной __name__, которая опре- делена в любой программе, и равна “__main__”, если скрипт запущен в качестве главной программы, и имя, если он импортирован. Например, mymodule.py может выглядеть вот так:
def hello
():
print
(
'Hello, world!'
)
def fib
(n):
a
=
b
=
1
for i
in range
(n
-
2
):
27.4. Создание своего модуля на Python
108

Самоучитель Python, Выпуск 0.2
a, b
=
b, a
+
b return b
if
__name__
==
"__main__"
:
hello()
for i
in range
(
10
):
print
(fib(i))
27.4. Создание своего модуля на Python
109

Глава
28
Объектно-ориентированное программирование. Общее представление
Сегодня мы поговорим об объектно-ориентированном программировании и о его приме- нении в python.
Объектно-ориентированное программирование (ООП) — парадигма программирова- ния, в которой основными концепциями являются понятия объектов и классов.
Класс — тип, описывающий устройство объектов. Объект — это экземпляр класса. Класс можно сравнить с чертежом, по которому создаются объекты.
Python соответствует принципам объектно-ориентированного программирования. В
python всё является объектами - и строки, и списки, и словари, и всё остальное.
Но возможности ООП в python этим не ограничены. Программист может написать свой тип данных (класс), определить в нём свои методы.
Это не является обязательным - мы можем пользоваться только встроенными объектами.
Однако ООП полезно при долгосрочной разработке программы несколькими людьми, так как упрощает понимание кода.
Приступим теперь собственно к написанию своих классов на python. Попробуем опреде- лить собственный класс:
>>>
# Пример самого простейшего класса class
A
:
pass
Теперь мы можем создать несколько экземпляров этого класса:
>>>
a
=
A()
>>>
b
=
A()
>>>
a arg
=
1
# у экземпляра a появился атрибут arg, равный 1
110

Самоучитель Python, Выпуск 0.2
>>>
b arg
=
2
# а у экземпляра b - атрибут arg, равный 2
>>>
print
(a arg)
1
Классу возможно задать собственные методы:
>>>
class
A
:
def g
(
self
):
# self - обязательный аргумент, содержащий в себе экземпляр
# класса, передающийся при вызове метода,
# поэтому этот аргумент должен присутствовать
# во всех методах класса.
return
'hello world'
>>>
a
=
A()
>>>
a g()
'hello world'
И напоследок еще один пример:
>>>
class
B
:
arg
=
'Python'
# Все экземпляры этого класса будут иметь атрибут arg,
# равный "Python"
# Но впоследствии мы его можем изменить def g
(
self
):
return self arg
>>>
b
=
B()
>>>
b g()
'Python'
>>>
B
g(b)
'Python'
>>>
b arg
=
'spam'
>>>
b g()
'spam'
111

Глава
29
Инкапсуляция, наследование, полиморфизм
Недавно мы говорили об основах объектно-ориентированного программирования в python
, теперь продолжим эту тему и поговорим о таких понятиях ООП, как инкапсу-
ляция, наследование и полиморфизм.
Инкапсуляция
Инкапсуляция — ограничение доступа к составляющим объект компонентам (методам и переменным). Инкапсуляция делает некоторые из компонент доступными только внут- ри класса.
Инкапсуляция в Python работает лишь на уровне соглашения между программистами о том, какие атрибуты являются общедоступными, а какие — внутренними.
Одиночное подчеркивание в начале имени атрибута говорит о том, что переменная или метод не предназначен для использования вне методов класса, однако атрибут доступен по этому имени.
class A:
def _private(self):
print("Это приватный метод!")
>>> a = A()
>>> a._private()
Это приватный метод!
Двойное подчеркивание в начале имени атрибута даёт большую защиту: атрибут стано- вится недоступным по этому имени.
112

Самоучитель Python, Выпуск 0.2
>>>
class
B
:
def
__private
(
self
):
print
(
"Это приватный метод!"
)
>>>
b
=
B()
>>>
b
__private()
Traceback (most recent call last):
File
""
, line
1
, in
AttributeError
: 'B' object has no attribute '__private'
Однако полностью это не защищает, так как атрибут всё равно остаётся доступным под именем _ИмяКласса__ИмяАтрибута:
>>>
b
_B__private()
Это приватный метод!
Наследование
Наследование подразумевает то, что дочерний класс содержит все атрибуты родитель- ского класса, при этом некоторые из них могут быть переопределены или добавлены в дочернем. Например, мы можем создать свой класс, похожий на словарь
:
>>>
class
Mydict
(
dict
):
def get
(
self
, key, default
=
0
):
return dict get(
self
, key, default)
>>>
a
=
dict
(a
=
1
, b
=
2
)
>>>
b
=
Mydict(a
=
1
, b
=
2
)
Класс Mydict ведёт себя точно так же, как и словарь, за исключением того, что метод get по умолчанию возвращает не None, а 0.
>>>
b[
'c'
]
=
4
>>>
print
(b)
{'a': 1, 'c': 4, 'b': 2}
>>>
print
(a get(
'v'
))
None
>>>
print
(b get(
'v'
))
0
Полиморфизм
Полиморфизм - разное поведение одного и того же метода в разных классах. Например,
мы можем сложить два числа, и можем сложить две строки. При этом получим разный результат, так как числа и строки являются разными классами.
29.2. Наследование
113

Самоучитель Python, Выпуск 0.2
>>>
1
+
1 2
>>>
"1"
+
"1"
'11'
29.3. Полиморфизм
114

Глава
30
Перегрузка операторов
Перегрузка операторов — один из способов реализации полиморфизма, когда мы можем задать свою реализацию какого-либо метода в своём классе.
Например, у нас есть два класса:
class
A
:
def go
(
self
):
print
(
'Go, A!'
)
class
B
(A):
def go
(
self
, name):
print
(
'Go,
{}
!'
format(name))
В данном примере класс B
наследует класс A, но переопределяет метод go, поэтому он имеет мало общего с аналогичным методом класса A.
Однако в python имеются методы, которые, как правило, не вызываются напрямую, а вы- зываются встроенными функциями или операторами.
Например, метод __init__ перегружает конструктор класса. Конструктор - создание экзем- пляра класса.
>>>
class
A
:
def
__init__
(
self
, name):
self name
=
name
>>>
a
=
A(
'Vasya'
)
>>>
print
(a name)
Vasya
Собственно, далее пойдёт список таких “магических” методов.
115

Самоучитель Python, Выпуск 0.2
__new__(cls[, ...]) — управляет созданием экземпляра. В качестве обязательного аргумента принимает класс (не путать с экземпляром). Должен возвращать экземпляр класса для его последующей его передачи методу __init__.
__init__(self[, ...]) - как уже было сказано выше, конструктор.
__del__(self ) - вызывается при удалении объекта сборщиком мусора.
__repr__(self ) - вызывается встроенной функцией repr; возвращает “сырые” данные, ис- пользующиеся для внутреннего представления в python.
__str__(self ) - вызывается функциями str, print и format. Возвращает строковое представ- ление объекта.
__bytes__(self ) - вызывается функцией bytes при преобразовании к байтам
__format__(self, format_spec) - используется функцией format (а также методом format у строк).
__lt__(self, other) - x < y вызывает x.__lt__(y).
__le__(self, other) - x <= y вызывает x.__le__(y).
__eq__(self, other) - x == y вызывает x.__eq__(y).
__ne__(self, other) - x != y вызывает x.__ne__(y)
__gt__(self, other) - x > y вызывает x.__gt__(y).
__ge__(self, other) - x >= y вызывает x.__ge__(y).
__hash__(self ) - получение хэш-суммы объекта, например, для добавления в словарь.
__bool__(self ) - вызывается при проверке истинности. Если этот метод не определён, вы- зывается метод __len__ (объекты, имеющие ненулевую длину, считаются истинными).
__getattr__(self, name) - вызывается, когда атрибут экземпляра класса не найден в обыч- ных местах (например, у экземпляра нет метода с таким названием).
__setattr__(self, name, value) - назначение атрибута.
__delattr__(self, name) - удаление атрибута (del obj.name).
__call__(self[, args...]) - вызов экземпляра класса как функции
__len__(self ) - длина объекта.
__getitem__(self, key) - доступ по индексу (или ключу).
__setitem__(self, key, value) - назначение элемента по индексу.
__delitem__(self, key) - удаление элемента по индексу.
__iter__(self ) - возвращает итератор для контейнера.
__reversed__(self ) - итератор из элементов, следующих в обратном порядке.
__contains__(self, item) - проверка на принадлежность элемента контейнеру (item in self ).
116

Самоучитель Python, Выпуск 0.2
Перегрузка арифметических операторов
__add__(self, other) - сложение. x + y вызывает x.__add__(y).
__sub__(self, other) - вычитание (x - y).
__mul__(self, other) - умножение (x * y).
__truediv__(self, other) - деление (x / y).
__floordiv__(self, other) - целочисленное деление (x // y).
__mod__(self, other) - остаток от деления (x % y).
__divmod__(self, other) - частное и остаток (divmod(x, y)).
__pow__(self, other[, modulo]) - возведение в степень (x ** y, pow(x, y[, modulo])).
__lshift__(self, other) - битовый сдвиг влево (x << y).
__rshift__(self, other) - битовый сдвиг вправо (x >> y).
__and__(self, other) - битовое И (x & y).
__xor__(self, other) - битовое ИСКЛЮЧАЮЩЕЕ ИЛИ (x ^ y).
__or__(self, other) - битовое ИЛИ (x | y).
Пойдём дальше.
__radd__(self, other),
__rsub__(self, other),
__rmul__(self, other),
__rtruediv__(self, other),
__rfloordiv__(self, other),
__rmod__(self, other),
__rdivmod__(self, other),
__rpow__(self, other),
__rlshift__(self, other),
__rrshift__(self, other),
__rand__(self, other),
__rxor__(self, other),
__ror__(self, other) - делают то же самое, что и арифметические операторы, перечислен- ные выше, но для аргументов, находящихся справа, и только в случае, если для левого операнда не определён соответствующий метод.
Например, операция x + y будет сначала пытаться вызвать x.__add__(y), и только в том слу- чае, если это не получилось, будет пытаться вызвать y.__radd__(x). Аналогично для осталь- ных методов.
30.1. Перегрузка арифметических операторов
117

Самоучитель Python, Выпуск 0.2
Идём дальше.
__iadd__(self, other) - +=.
__isub__(self, other) - -=.
__imul__(self, other) - *=.
__itruediv__(self, other) - /=.
__ifloordiv__(self, other) - //=.
__imod__(self, other) - %=.
__ipow__(self, other[, modulo]) - **=.
__ilshift__(self, other) - <<=.
__irshift__(self, other) - >>=.
__iand__(self, other) - &=.
__ixor__(self, other) - ^=.
__ior__(self, other) - |=.
__neg__(self ) - унарный -.
__pos__(self ) - унарный +.
__abs__(self ) - модуль (abs()).
__invert__(self ) - инверсия (

).
__complex__(self ) - приведение к complex.
__int__(self ) - приведение к int.
__float__(self ) - приведение к float.
__round__(self[, n]) - округление.
__enter__(self ), __exit__(self, exc_type, exc_value, traceback) - реализация менеджеров кон- текста.
Рассмотрим некоторые из этих методов на примере двухмерного вектора, для которого переопределим некоторые методы:
import math class
Vector2D
:
def
__init__
(
self
, x, y):
self x
=
x self y
=
y def
__repr__
(
self
):
return
'Vector2D(
{}
,
{}
)'
format(
self x,
self y)
def
__str__
(
self
):
return
'(
{}
,
{}
)'
format(
self x,
self y)
1   ...   4   5   6   7   8   9   10   11   12


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