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

С. В. Вабищевич инженерпрограммист компании ооо ск хайникс мемори солюшнс Восточная Европа


Скачать 1.28 Mb.
НазваниеС. В. Вабищевич инженерпрограммист компании ооо ск хайникс мемори солюшнс Восточная Европа
Дата22.11.2021
Размер1.28 Mb.
Формат файлаpdf
Имя файлаKositsin.pdf
ТипУчебно-методическое пособие
#278468
страница4 из 9
1   2   3   4   5   6   7   8   9
partialвозвращает новую функцию, фиксируя некото- рые аргументы (замена, например,
lambda x: f(x, True); а также
partialmethodс Python 3.4);

54

lru_cache – декоратор для сохранения результатов функции в LRU‑кеше (начиная с Python 3.2);

singledispatch – декоратор, позволяющий вызывать функцию в зависимости от типа ее аргумента (c Python 3.4, примеры)
1
Также в Python 3.4 был добавлен модуль
enum, содержащий класс
Enum и IntEnum, реализующие перечисляемый тип.
ЛОГИРОВАНИЕ
Вместо использования вывода на экран удобно использо‑
вать настраиваемый логгер, который может фильтровать сообщения в зависимости от их значимости и сохранять данные в нескольких местах одновременно.
Создать новый logger (типа
Logger) можно вызовом функции
getLogger в модуле logging, передав ему некоторое имя.
Замечание. Если передать имя существующего логгера в метод
getLogger, то будет возвращен уже существующий логгер с таким именем.
>>> import sys
>>> import logging
>>> import datetime
>>>
>>>logger = logging.getLogger(__name__)
>>>logger.setLevel(logging.INFO)
>>>logger.addHandler(logging.handlers.StreamHandler
(sys.stdout))
>>>logger.info(“current year’s%d”, datetime.datetime.
today().year)
Логировать сообщение можно с помощью методов
debug, info,
warning, error, critical или общего log.
Метод
setLevel нужен для установки уровня чувствительности
(verbosity) логгера.
Добавить обработчик можно методом
addHandler, фильтр –
addFilter.
Реализованные обработчики:
StreamHandler, FileHandler,
RotatingFileHandler, SocketHandler, etc.
Замечания. В Python 3 Handlers и Filters расположены во вложен‑
ных модулях, а содержимое модуля datetime перемещено.
1 https://docs.python.org/3/library/functools.html

55
Все handler’ы и filterer’ы имеют базовые классы –
logging.
Handler и logging.Filterer.
Конфигурация логгера может быть сохранена в файле и загруже- на с помощью
logging.config.dictConfig.
Примеры работы с логгером приведены на странице с докумен- тацией
1
РАБОТА С ФАЙЛОВОЙ СИСТЕМОЙ
В стандартной библиотеке есть несколько модулей, отве- чающих за файловую систему.
Модуль
os.path служит в основном для работы с путями:

join – объединяет пути;

abspath – возвращает абсолютный путь;

relpath – возвращает относительный путь;

commonprefix – возвращает общую часть у двух путей;

split – разделяет путь на папку и файл или корень и вложен- ную папку;

normpath – нормализует путь;

walk – рекурсивно обходит дерево папок;

getsize – возвращает размер файла в байтах;

exists – проверяет, существует ли указанный путь;

isfile – проверяет, является ли путь существующим файлом.
Для работы с файловой системой используется модуль
os:

listdir – возвращает файлы и папки, содержащиеся в указан- ной директории;

mkdir – создает подпапку в папке;

makedirs – рекурсивно создает директории;

remove – удаляет файл;

rmdir – удаляет директорию;

rename – переименовывает файл или папку;

stat – возвращает информацию по файловому объекту.
Для копирования и удаления файлов используется модуль
shutil:

copyкопирует файл или папку;

move – перемещает файл или папку;

rmtree – рекурсивно удаляет папку.
Модули
glob и fnmatch предназначены для поиска файлов и па- пок по шаблонам с wildcard’ами, для сравнения файлов есть модуль
filecmp.
1
https://docs.python.org/3/howto/logging-cookbook.html

56
В Python 3.6 появились полноценная библиотека для работы од- новременно с путями и файловыми объектами –
Pathlib (PEP-428)
1
,
а также функция
os.scandir – улучшенный аналог os.walk (PEP-519)
2
РАБОТА С СИСТЕМОЙ
Модуль
os также содержит множество констант и функций для работы с системой:

chdir – меняет текущую рабочую директорию;

getcwd – отображает текущую рабочую директорию;

getenv, putenv, unsetenv – работа с переменными окружения;

environ – список переменных окружения;

extsep – значение разделителя имени файла и расширения.
Все функции являются специфическими для системы (system
specific) и могут отсутствовать. Для управления процессами исполь- зуются функции
abort и kill.
ПАРСИНГ АРГУМЕНТОВ КОМАНДНОЙ СТРОКИ
Для парсинга аргументов командной строки используют
ArgumentParser, находящийся в модуле argparse.
Рассмотрим пример, в котором передается одно или более целые числа (integers), которые суммируются или среди которых находится максимальное в зависимости от того, указан аргумент sum или нет.
>>> import argparse
>>>
>>>parser = argparse.ArgumentParser(description=’Process
some integers.’)
>>>
>>>parser.add_argument(‘integers’,
type=int, nargs=’+’,
help=’an integer for the
accumulator’)
>>>parser.add_argument(‘—sum’,
dest=’accumulate’,
action=’store_const’,
1
https://www.python.org/dev/peps/pep-0428 2
https://www.python.org/dev/peps/pep-0519

57
const=sum, default=max,
help=’sum the integers
(default: find the max)’)
>>>
>>>args = parser.parse_args()
>>> print(args.accumulate(args.integers))
Методы
parse_args и parse_known_args принимают некоторый список аргументов (по умолчанию
sys.argv), парсят его и возвра- щают объект
Namespace, который содержит все полученные пере- менные. Разница в методах в том, что
parse_known_args не броса- ет исключение, если переданы аргументы, отличные от указанных в argument parser’е.
Информация об аргументе добавляется с помощью метода
add_
argument:
– имена переменных через «-» (dash), «—» (double dash) или без них;
dest – имя переменной, в которой хранится значение;
type – преобразование типа;
action – действие при получении аргумента (store, store_true,
append, etc.);
nargs – количество аргументов (1, 1 и более, 0 и более);
default – значение по умолчанию (если не передан);
required – обязательный аргумент;
choices – список возможных значений;
– help – описание аргумента.
Замечание. Произвольную строку запуска можно разбить на спи- сок с помощью модуля
shlex.
ОТВЕТЫ
Сортировка – TimSort (производная merge sort и insertion sort; https://en.wikipedia.org/wiki/Timsort).
Сравнение двух списков из примера даст [1, 2] меньше [2], по- скольку сравнение лексикографическое.
Сравнение же списка со строкой в Python 3 породит исключе- ние. В Python 2 применялись неочевидные методы сравнения объ- ектов разных типов.
Hash- функция в Python < 3.4 – FNV, далее – SipHash (PEP456)
1 1
https://www.python.org/dev/peps/pep-0456

58
В стандартной библиотеке для поиска подстрок в строке исполь- зуется алгоритм Бойера – Мура (https://en.wikipedia.org/wiki/Boyer–
Moore_string_search_algorithm).
При попытке изменить список, который является элементом кор- тежа с помощью присваивания, произойдет следующее:
– выполнится сложение – в список добавится новый элемент;
– при выполнении присваивания произойдет исключение
TypeError, что tuple не может быть модифицирован.
Для корректного изменения списка следует использовать мето- ды
append и extend.
В случае передачи в метод
zip коллекций (итераторов по коллек- циям) разной длины, итерирование закончится при достижении кон- ца наименьшей коллекции.
В случае итераторов важно, какой итератор будет исчерпан пер- вым.
>>> i1, i2 = iter(range(5)), iter(range(2))
>>> for x, y in zip(i1, i2):

pass
>>> assert next(i1) == 3
Очистить список, не удалив его, можно так:
>>> x = []
>>> del x[:]
>>> x[:] = [] # эквивалентная запись
Строки модуля интерпретируются последовательно. При по- пытке создания объекта
f – функции аргументы по умолчанию будут также интерпретированы и сохранены в данном объекте.
Поскольку функция
g объявлена ниже, произойдет исключение
NameError, что такого имени нет. Обратите внимание, что зна- чения аргументов по умолчанию создаются
только один раз при загрузке модуля.
Если функция имеет неименованный variadic параметр (Python 3), но variadic аргументы переданы, то произойдет исключение
TypeError.
Модифицировать локальные переменные через словарь
locals() крайне не рекомендуется, хоть исключения и не будет. Следует толь- ко получать значения.
Пустая lambda- функция имеет следующий вид:
>>> lambda: None

Если количество аргументов для подстановки не совпадает с ко- личеством в шаблоне или один из требуемых именованных аргумен- тов не передан, произойдет исключение
TypeError.
Однако для подстановки можно передать словарь, в котором зна- чений больше, чем требуется. Ошибки в таком случае не будет.
ПОЛЕЗНЫЕ ССЫЛКИ
– Сайт Jupyter (инструкция по установке и документация: https://jupyter.org
– Как использовать сразу две версии Python: http://ipython.
readthedocs.io/en/stable/install/kernel_install.html и https://stackover- flow.com/questions/30492623/using- both- python-2-x- and- python-3-x- in- ipython- notebook
– Документация по «магическим» выражениям Jupyter: http://
ipython.readthedocs.io/en/stable/interactive/magics.html
– Стандартная библиотека содержит много полезного: https://
docs.python.org/2.7/library; https://docs.python.org/3/library
– Подробнее механизм импортов (Python 3):
https://docs.python.org/3.7/library/modules.html https://docs.python.org/3.7/tutorial/modules.html https://docs.python.org/3.7/reference/import.html
– Для Python 2 документация механизма импортов:
https://docs.python.org/2.7/library/modules.html https://docs.python.org/2.7/tutorial/modules.html

60
Глава
3
ОБЪЕКТНО ОРИЕНТИРОВАННОЕ
ПРОГРАММИРОВАНИЕ НА PYTHON
3.1. ОБЩИЕ ПОНЯТИЯ КЛАССОВ И ОБЪЕКТОВ
Класс – тип данных, описывает модель некоторой сущности.
Объект – реализация этого класса.
Пример:
int – класс, 42 – объект этого класса (типа int).
Пустой класс в Python определяется следующим образом:
>>> class Empty(object):
>>> pass
3.2. МЕТОДЫ КЛАССОВ
Функции – вызываемые с помощью оператора «()» (скоб- ки) объекты.
Методы – функции, которые первым аргументом принимают эк- земпляр соответствующего класса (обычно именуют его
self).
>>> class Greeter(object):
>>>
def greet(self):
>>>
print («hey, guys!»)
Атрибуты классов – поля, характеризующие класс и работу с ним. Методы также являются атрибутами – callable- объектами, которые работают с другими атрибутами класса.
АТРИБУТЫ ОБЪЕКТОВ
>>> class Greeter(object):
>>> def set_name(self, name):
>>> self.name = name
>>>
>>> def greet(self):
>>>
print “hey,%s!”% self.name
>>>
>>> print(Greeter().greet())

61
Поле классу присвоится лишь во время исполнения после вызова метода set_name, поэтому в данном случае произойдет
AttributeError.
АТРИБУТЫ КЛАССОВ
>>> class Greeter(object):
>>>
DEFAULT_NAME = ‘guys’
>>>
>>>
def __init__(self, name=None):
>>> self.name = name or
self.__class__.DEFAULT_NAME
>>>
>>> g = Greeter()
Хорошим правилом будет установка всех атрибутов в конструк- торе со значениями по умолчанию или
None.
Здесь DEFAULT_NAME – атрибут класса, name – атрибут экзем- пляра класса.
Важно! Значение DEFAULT_NAME можно указать в качестве зна- чения по умолчанию в функции __init__ – оно уже будет доступно в контексте функции, – но при изменении значения переменной зна- чение по умолчанию не изменится. В примере же поведение функ- ции иное – значение обновляется при каждом вызове.
>>> class Greeter(object):
>>>
DEFAULT_NAME = ‘guys’
К атрибуту класса DEFAULT_NAME можно обращаться:
– по имени класса: Greeter.DEFAULT_NAME
– как к атрибуту класса: self.__class__.DEFAULT_NAME
– как к атрибуту экземпляра класса: self.DEFAULT_NAME
Важно! По сути, атрибуты классов – статические поля, которые доступны всем его экземплярам и разделяются (shared) между ними, а также по имени класса.
ИМЕНОВАНИЕ ПОЛЕЙ КЛАССА
Для определения конструктора, переопределения операто- ров, получения служебной информации в Python используются атри- буты со специальными именами вида
__*__ (__init__, __class__ и т. п.).

62
Все атрибуты доступны извне класса (являются
public).
Для обозначения
protected атрибута используют префикс «_»
(underscore), для
private – «__» (two underscores).
Важно! Доступ к protected и private-атрибутам по- прежнему возможен извне – название служит
предупреждением.
Можно указать следующие преимущества того, что все перемен- ные доступны вне зависимости от их имени:
– легче отлаживать и проверять код, у IDE больше возможностей;
– легче писать группы классов, связанные друг с другом;
– можно «перехватывать» изменение атрибутов.
Из минусов очевиден такой: при желании «защиту» можно обойти.
Замечание. Многие IDE предупреждают о том, что происходит доступ к
protected или private-атрибуту извне класса.
Обычно
private-атрибуты используют крайне редко, ведь доступ к ним извне все равно возможен: они доступны как __C_name, где C – имя класса, а name – имя атрибута.
Пример реализации инкапсуляции
>>> class Animal(object):
>>>
def __init__(self, age=0):
>>>
self._age = age
>>>
>>>
def get_age(self):
>>>
“””age of animal“””
>>>
return self._age
>>>
>>>
def set_age(self, age):
>>>
assert age >= self._age
>>>
self._age = age
>>>
>>>
def increment_age(self):
>>>
self.set_age(1 + self.get_age())
СВОЙ СТВА
– ДЕКОРАТОР PROPERTY
Проблема реализации в предыдущем примере в том, что для каждого атрибута помимо методов работы с ним нужны getter и setter, иначе атрибут можно произвольно изменять извне.

63
Чтобы явно не создавать функции, а скрыть истинные обраще- ния, можно воспользоваться декоратором property, тем самым соз- дав свой ство:
>>> class Animal(object):
>>>
def __init__(self, age=0):
>>>
self._age = age
>>>
>>>
@property
>>>
def age(self):
>>>
“””age of animal”””
>>>
return self._age
>>>
>>>
@age.setter
>>>
def age(self, age):
>>>
assert age >= self._age
>>>
self._age = age
Чтобы не хранить атрибуты, напрямую зависимые от других, можно реализовать доступ к ним с помощью свой ств.
>>> class PathInfo(object):
>>>
def __init__(self, file_path):
>>>
self._file_path = file_path
>>>
>>>
@property
>>>
def file_path(self):
>>>
return self._file_path
>>>
>>>
@property
>>>
def folder(self):
>>>
return os.path.dirname(self.file_path)
ДЕКОРАТОРЫ STATICMETHOD И CLASSMETHOD
Для реализации статических методов в классах исполь- зуют специальный декоратор
staticmethod, при этом параметр self при вызове не передается.
>>> class A(object):
>>>
@staticmethod
>>>
def f(a, b):
>>>
return a + b

64
>>>
>>> A.f(1, 2) == A().f(1, 2)
True
В функцию, декорированную
classmethod, первым параметром вместо объекта класса (instance) передается сам класс (параметр обычно называют
cls).
МАГИЧЕСКИЕ МЕТОДЫ
Общие методы
Методы со специальными именами вида
__*__ называют магическими (или же dunder-методы). Они отвечают за многие опе- рации с объектом. Список магических методов можно увидеть в опи- сании DataModel (Python 2.x)
1
, (Python 3.x)
2
, а также на странице мо- дуля
operator.
За создание, инициализацию и удаление класса отвечают мето- ды с именами __
new__, __init__, __del__ соответственно.
Метод __
call__ переопределяет оператор вызова () (круглые скобки).
Метод __
len__ – взятие длины (может вызываться как len(.); в Python 3 есть также
length_hint).
Приведение типа
Методы приведения к строке называются __
repr__, __str__ и __
unicode__ (Python 2.x) или __bytes__ и __str__ (Python 3.x)
Методы приведения к типу
bool – __nonzero__ (Python 2.x) или
__
bool__ (Python 3.x)
Преобразовать к строке объект можно, вызвав
str(x) или x.__str__
(), к
boolbool(x) или x.__bool__() (nonzero).
Если метод преобразования к
bool не реализован, возвращает- ся результат метода
__len__, а если и его нет, то все объекты преоб- разуются к
1   2   3   4   5   6   7   8   9


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