>>> class Bill():
…·····def __init__(self, description):
…·········self.description = description
…
>>> class Tail():
…·····def __init__(self, length):
…·········self.length = length
…
>>> class Duck():
…·····def __init__(self, bill, tail):
…·········self.bill = bill
…·········self.tail = tail
…·····def about(self):
…·········print('This duck has a', bill.description, 'bill and a',
··················tail.length, 'tail')
…
>>> tail = Tail('long')
>>> bill = Bill('wide orange')
>>> duck = Duck(bill, tail)
>>> duck.about()
This duck has a wide orange bill and a long tail
Когда лучше использовать классы и объекты, а когда — модули
Рассмотрим несколько рекомендаций, которые помогут вам понять, где лучше разместить свой код — в классе или в модуле.
• Объекты наиболее полезны, когда вам нужно иметь некоторое количество отдельных экземпляров с одинаковым поведением (методами), но различающихся внутренним состоянием (атрибутами).
• Классы, в отличие от модулей, поддерживают наследование.
• Если вам нужен только один объект, модуль подойдет лучше. Независимо от того, сколько обращений к модулю имеется в программе, будет загружена только одна копия. (Программистам на Java и С++: если вы знакомы с книгой Эриха Гаммы «Приемы объектно-ориентированного проектирования. Паттерны проектирования» (Gamma E. Design Patterns: Elements of Reusable Object-Oriented Software), можете использовать модули в Python как синглтоны.)
• Если у вас есть несколько переменных, которые содержат разные значения и могут быть переданы как аргументы в несколько функций, лучше всего определить их как классы. Например, вы можете использовать словарь с ключами size и color, чтобы представить цветное изображение. Вы можете создать разные словари для каждого изображения в программе и передавать их в качестве аргументов в функции scale() и transform(). По мере добавления новых ключей и функций может начаться путаница. Более последовательно было бы определить класс Image с атрибутами size или color и методами scale() и transform(). В этом случае все данные и методы для работы с цветными изображениями будут определены в одном месте.
• Используйте простейшее решение задачи. Словарь, список или кортеж проще, компактнее и быстрее, чем модуль, который, в свою очередь, проще, чем класс.
Совет от Гвидо ван Россума: «Избегайте усложнения структур данных. Кортежи лучше объектов (можно воспользоваться именованными кортежами). Предпочитайте простые поля функциям, геттерам и сеттерам. Используйте больше чисел, строк, кортежей, списков, множеств, словарей. Взгляните также на библиотеку collections, особенно на класс deque».
Именованные кортежи. Поскольку Гвидо только что упомянул их, а я про них еще не говорил, самое время рассмотреть именованные кортежи. Именованный кортеж — это подкласс кортежей, с помощью которых вы можете получить доступ к значениям по имени (с помощью конструкции. name) и позиции (с помощью конструкции [offset]).
Рассмотрим пример из предыдущего раздела и преобразуем класс Duck в именованный кортеж, сохранив bill и tail как простые строковые аргументы. Функцию namedtuple можно вызвать, передав ей два аргумента:
• имя;
• строку, содержащую имена полей, разделенные пробелами.
Именованные кортежи не поддерживаются Python автоматически, вам понадобится загрузить отдельный модуль для того, чтобы их использовать. Мы сделаем это в первой строке следующего примера:
>>> from collections import namedtuple
>>> Duck = namedtuple('Duck', 'bill tail')
>>> duck = Duck('wide orange', 'long')
>>> duck
Duck(bill='wide orange', tail='long')
>>> duck.bill
'wide orange'
>>> duck.tail
'long'
Именованный кортеж можно сделать также на основе словаря:
>>> parts = {'bill': 'wide orange', 'tail': 'long'}
>>> duck2 = Duck(**parts)
>>> duck2
Duck(bill='wide orange', tail='long')
В коде, показанном ранее, обратите внимание на конструкцию **parts. Это аргумент — ключевое слово. Он извлекает ключи и значения словаря parts и передает их как аргументы в Duck(). По эффекту это похоже на следующий код:
>>> duck2 = Duck(bill = 'wide orange', tail = 'long')
Именованные кортежи неизменяемы, но вы можете заменить одно или несколько полей и вернуть другой именованный кортеж:
>>> duck3 = duck2._replace(tail='magnificent', bill='crushing')
>>> duck3
Duck(bill='crushing', tail='magnificent')
Мы могли бы объявить duck как словарь:
>>> duck_dict = {'bill': 'wide orange', 'tail': 'long'}
>>> duck_dict
{'tail': 'long', 'bill': 'wide orange'}
Вы можете добавить поля в словарь:
>>> duck_dict['color'] = 'green'
>>> duck_dict
{'color': 'green', 'tail': 'long', 'bill': 'wide orange'}
Но не в именованный кортеж:
>>> duck.color = 'green'
Traceback (most recent call last):
··File "", line 1, in
AttributeError: 'dict' object has no attribute 'color'
Вспомним плюсы использования именованного кортежа.
• Они выглядят и действуют как неизменяемый объект.
• Они более эффективны, чем объекты, с точки зрения времени и занимаемого места.
• Вы можете получить доступ к атрибутам с помощью точки вместо квадратных скобок, характерных для словарей.
• Вы можете использовать их как ключ словаря.
Упражнения
1. Создайте класс, который называется Thing, не имеющий содержимого, и выведите его на экран. Затем создайте объект example этого класса и также выведите его. Совпадают ли выведенные значения?
2. Создайте новый класс с именем Thing2 и присвойте его атрибуту letters значение 'abc'. Выведите на экран значение атрибута letters.
3. Создайте еще один класс, который, конечно же, называется Thing3. В этот раз присвойте значение 'xyz' атрибуту объекта, который называется letters. Выведите на экран значение атрибута letters. Понадобилось ли вам создавать объект класса, чтобы сделать это?
4. Создайте класс, который называется Element, имеющий атрибуты объекта name, symbol и number. Создайте объект этого класса со значениями 'Hydrogen', 'H' и 1.
5. Создайте словарь со следующими ключами и значениями: 'name': 'Hydrogen', 'symbol': 'H', 'number': 1. Далее создайте объект с именем hydrogen класса Element с помощью этого словаря.
6. Для класса Element определите метод с именем dump(), который выводит на экран значения атрибутов объекта (name, symbol и number). Создайте объект hydrogen из этого нового определения и используйте метод dump(), чтобы вывести на экран его атрибуты.
7. Вызовите функцию print(hydrogen). В определении класса Element измените имя метода dump на __str__, создайте новый объект hydrogen и затем снова вызовите метод print(hydrogen).
8. Модифицируйте класс Element, сделав атрибуты name, symbol и number закрытыми. Определите для каждого атрибута свойство получателя, возвращающее значение соответствующего атрибута.
9. Определите три класса: Bear, Rabbit и Octothorpe. Для каждого из них определите всего один метод — eats(). Он должен возвращать значения 'berries' (для Bear), 'clover' (для Rabbit) или 'campers' (для Octothorpe). Создайте по одному объекту каждого класса и выведите на экран то, что ест указанное животное.
10. Определите три класса: Laser, Claw и SmartPhone. Каждый из них имеет только один метод — does(). Он возвращает значения 'disintegrate' (для Laser), 'crush' (для Claw) или 'ring' (для SmartPhone). Далее определите класс Robot, который содержит по одному объекту каждого из этих классов. Определите метод does() для класса Robot, который выводит на экран все, что делают его компоненты.
Глава 7. Работаем с данными профессионально
Из этой главы вы узнаете множество приемов приручения данных. Большинство из них касаются встроенных типов данных.
•
Оглавление
-
Введение
-
Аудитория
-
Краткое описание
-
Версии Python
-
Соглашения, принятые в этой книге
-
Использование примеров кода
-
Как с нами связаться
-
Благодарности
-
Об авторе
-
Глава 1. Python: с чем его едят
-
Python в реальном мире
-
Python против языка Х
-
Почему же Python?
-
Когда не стоит использовать Python
-
Python 2 против Python 3
-
Установка Python
-
Запуск Python
-
Интерактивный интерпретатор
-
Файлы Python
-
Что дальше?
-
Момент просветления
-
Упражнения
-
Глава 2. Ингредиенты Python: числа, строки и переменные
-
Переменные, имена и объекты
-
Числа
-
Целые числа
-
Приоритет операций
-
Системы счисления
-
Преобразования типов
-
Насколько объемен тип int?
-
Числа с плавающей точкой
-
Математические функции
-
Строки
-
Создаем строки с помощью кавычек
-
Преобразование типов данных с помощью функции str()
-
Создаем управляющие символы с помощью символа \
-
Объединяем строки с помощью символа +
-
Размножаем строки с помощью символа *
-
Извлекаем символ с помощью символов []
-
Извлекаем подстроки с помощью оператора [ start: end: step ]
-
Получаем длину строки с помощью функции len()
-
Разделяем строку с помощью функции split()
-
Объединяем строки с помощью функции join()
-
Развлекаемся со строками
-
Регистр и выравнивание
-
Заменяем символы с помощью функции replace()
-
Больше действий со строками
-
Упражнения
-
Глава 3. Наполнение Python: списки, кортежи, словари и множества
-
Списки и кортежи
-
Списки
-
Создание списков с помощью оператора [] или метода list()
-
Преобразование других типов данных в списки с помощью функции list()
-
Получение элемента с помощью конструкции [смещение]
-
Списки списков
-
Изменение элемента с помощью конструкции [смещение]
-
Отрежьте кусочек — извлечение элементов с помощью диапазона смещений
-
Добавление элемента в конец списка с помощью метода append()
-
Объединяем списки с помощью метода extend() или оператора +=
-
Добавление элемента с помощью функции insert()
-
Удаление заданного элемента с помощью функции del
-
Удаление элемента по значению с помощью функции remove()
-
Получение заданного элемента и его удаление с помощью функции pop()
-
Определение смещения элемента по значению с помощью функции index()
-
Проверка на наличие элемента в списке с помощью оператора in
-
Определяем количество включений значения с помощью функции count()
-
Преобразование списка в строку с помощью функции join()
-
Меняем порядок элементов с помощью функции sort()
-
Получение длины списка с помощью функции len()
-
Присваивание с помощью оператора =, копирование с помощью функции copy()
-
Кортежи
-
Создание кортежей с помощью оператора ( )
-
Кортежи против списков
-
Словари
-
Создание словаря с помощью {}
-
Преобразование с помощью функции dict()
-
Добавление или изменение элемента с помощью конструкции [ключ]
-
Объединение словарей с помощью функции update()
-
Удаление элементов по их ключу с помощью del
-
Удаление всех элементов с помощью функции clear()
-
Проверяем на наличие ключа с помощью in
-
Получение элемента словаря с помощью конструкции [ключ]
-
Получение всех ключей с помощью функции keys()
-
Получение всех значений с помощью функции values()
-
Получение всех пар «ключ — значение» с помощью функции items()
-
Присваиваем значения с помощью оператора =, копируем их с помощью функции copy()
-
Множества
-
Создание множества с помощью функции set()
-
Преобразование других типов данных с помощью функции set()
-
Проверяем на наличие значения с помощью ключевого слова in
-
Комбинации и операторы
-
Сравнение структур данных
-
Создание крупных структур данных
-
Упражнения
-
Глава 4. Корочка Python: структуры кода
-
Комментируем с помощью символа #
-
Продлеваем строки с помощью символа \
-
Сравниваем выражения с помощью операторов if, elif и else
-
Повторяем действия с помощью while
-
Прерываем цикл с помощью break
-
Пропускаем итерации с помощью continue
-
Проверяем, завершился ли цикл заранее, с помощью else
-
Выполняем итерации с помощью for
-
Прерываем цикл с помощью break
-
Пропускаем итерации с помощью continue
-
Проверяем, завершился ли цикл заранее, с помощью else
-
Итерирование по нескольким последовательностям с помощью функции zip()
-
Генерирование числовых последовательностей с помощью функции range()
-
Прочие итераторы
-
Включения
-
Включение списков
-
Включение словаря
-
Включение множества
-
Включение генератора
-
Функции
-
Позиционные аргументы
-
Аргументы — ключевые слова
-
Указываем значение параметра по умолчанию
-
Получаем позиционные аргументы с помощью *
-
Получение аргументов — ключевых слов с помощью **
-
Строки документации
-
Функции — это объекты первого класса
-
Внутренние функции
-
Замыкания
-
Анонимные функции: функция lambda()
-
Генераторы
-
Декораторы
-
Простра нства имен и область определения
-
Обработка ошибок с помощью try и except
-
Создание собственных исключений
-
Упражнения
-
Глава 5. Py Boxes: модули, пакеты и программы
-
Отдельные программы
-
Аргументы командной строки
-
Модули и оператор import
-
Импортируем модуль
-
Импортируем модуль с другим именем
-
Импортируем только самое необходимое
-
Каталоги поиска модулей
-
Пакеты
-
Стандартная библиотека Python
-
Обработка отсутствующих ключей с помощью функций setdefault() и defaultdict()
-
Подсчитываем элементы с помощью функции Counter()
-
Упорядочиваем по ключу с помощью OrderedDict()
-
Стек + очередь == deque
-
Итерируем по структурам кода с помощью itertools
-
Выводим данные на экран красиво с помощью функции pprint()
-
Нужно больше кода
-
Упражнения
-
Глава 6. Ой-ой-ой: объекты и классы
-
Что такое объекты
-
Определяем класс с помощью ключевого слова class
-
Наследование
-
Перегрузка метода
-
Добавление метода
-
Просим помощи у предка с помощью ключевого слова super
-
В защиту self
-
Получаем и устанавливаем значение атрибутов с помощью свойств
-
Искажение имен для безопасности
-
Типы методов
-
Утиная типизация
-
Особые методы
-
Композиция
-
Когда лучше использовать классы и объекты, а когда — модули
-
Упражнения
-
Глава 7. Работаем с данными профессионально
-
Текстовые строки
-
Unicode
-
Формат
-
Совпадение с регулярными выражениями
-
Бинарные данные
-
bytes и bytearray
-
Преобразуем бинарные данные с помощью модуля struct
-
Другие инструменты для работы с бинарными данными
-
Преобразование байтов/строк с помощью функции binascii()
-
Битовые операторы
-
Упражнения
-
Глава 8. Данные должны куда-то попадать
-
Ввод информации в файлы и ее вывод из них
-
Запись в текстовый файл с помощью функции write()
-
Считываем данные из текстового файла с помощью функций read(), readline() и readlines()
-
Записываем данные в бинарный файл с помощью функции write()
-
Читаем бинарные файлы с помощью функции read()
-
Закрываем файлы автоматически с помощью ключевого слова with
-
Меняем позицию с помощью функции seek()
-
Структурированные текстовые файлы
-
CSV
-
XML
-
HTML
-
JSON
-
YAML
-
Безопасность
-
Конфигурационные файлы
-
Другие форматы обмена данными
-
Сериализация с помощью pickle
-
Структурированные бинарные файлы
-
Электронные таблицы
-
HDF5
-
Реляционные базы данных
-
SQL
-
DB-API
-
SQLite
-
MySQL
-
PostgreSQL
-
SQLAlchemy
-
Хранилища данных NoSQL
-
Семейство dbm
-
Memcached
-
Redis
-
Прочие серверы NoSQL
-
Full-Text Databases
-
Упражнения
-
Глава 9. Распутываем Всемирную паутину
-
Веб-клиенты
-
Тестируем с telnet
-
Стандартные веб-библиотеки Python
-
За пределами стандартной библиотеки: requests
-
Веб-серверы
-
Простейший веб-сервер Python
-
Web Server Gateway Interface
-
Фреймворки
-
Bottle
-
Flask
-
Веб-серверы, не использующие Python
-
Другие фреймворки
-
Веб-сервисы и автоматизация
-
Модуль webbrowser
-
API для Сети и Representational State Transfer
-
JSON
-
Поиск и выборка данных
-
Получаем HTML-код с помощью BeautifulSoup
-
Упражнения
-
Глава 10. Системы
-
Файлы
-
Создаем файл с помощью функции open()
-
Проверяем существование файла с помощью функции exists()
-
Проверяем тип с помощью функции isfile()
-
Копируем файлы с помощью функции copy()
-
Изменяем имена файлов с помощью функции rename()
-
Создаем ссылки с помощью link() или symlink()
-
Изменяем разрешения с помощью функции chmod()
-
Изменение владельца файла с помощью функции chown()
-
Получаем pathname с помощью функции abspath()
-
Получаем символьную ссылку с помощью функции realpath()
-
Удаляем файл с помощью функции remove()
-
Каталоги
-
Создаем каталог с помощью функции mkdir()
-
Удаляем каталог с помощью функции rmdir()
-
Выводим на экран содержимое каталога с помощью функции listdir()
-
Изменяем текущий каталог с помощью функции chdir()
-
Перечисляем совпадающие файлы с помощью функции glob()
-
Программы и процессы
-
Создаем процесс с помощью модуля subprocess
-
Создаем процесс с помощью модуля multiprocessing
-
Убиваем процесс с помощью функции terminate()
-
Календари и часы
-
Модуль datetime
-
Модуль time
-
Читаем и записываем дату и время
-
Альтернативные модули
-
Упражнения
-
Глава 11. Конкуренция и сети
-
Конкуренция
-
Очереди
-
Процессы
-
Потоки
-
Зеленые потоки и gevent
-
twisted
-
asyncio
-
Redis
-
Помимо очередей
-
Сети
-
Шаблоны
-
Модель публикации-подписки
-
TCP/IP
-
Сокеты
-
ZeroMQ
-
Scapy
-
Интернет-службы
-
Веб-службы и API
-
Удаленная обработка
-
Большие данные и MapReduce
-
Работаем в облаках
-
Упражнения
-
Глава 12. Быть питонщиком
-
О программировании
-
Ищем код на Python
-
Установка пакетов
-
Используем pip
-
Менеджер пакетов
-
Установка из исходного кода
-
Интегрированные среды разработки
-
IDLE
-
PyCharm
-
IPython
-
Именуйте и документируйте
-
Тестируем код
-
pylint, pyflakes и PEP-8
-
unittest
-
Пакет doctest
-
Пакет nose
-
Другие фреймворки для тестирования
-
Постоянная интеграция
-
Отлаживаем свой код
-
Отлаживаем с помощью pdb
-
***
-
Записываем в журнал сообщения об ошибках
-
Оптимизируем код
-
Измеряем время
-
Алгоритмы и структуры данных
-
Cython, NumPy и расширения C
-
PyPy
-
Управление исходным кодом
-
Mercurial
-
Git
-
Клонируйте эту книгу
-
Как узнать больше
-
Книги
-
Сайты
-
Группы
-
Конференции
-
Coming Attractions
-
Приложение A. Пи-Арт
-
2D-графика
-
Стандартная библиотека
-
PIL и Pillow
-
ImageMagick
-
Графические пользовательские интерфейсы (Graphical User Interface, GUI)
-
Трехмерная графика и анимация
-
Диаграммы, графики и визуализация
-
matplotlib
-
bokeh
-
Игры
-
Аудио и музыка
-
Приложение Б. За работой
-
The Microsoft Office Suite
-
Выполняем бизнес-задачи
-
Обработка бизнес-данных
-
Извлечение, преобразование и загрузка
-
Дополнительные источники информации
-
Python в области финансов
-
Безопасность бизнес-данных
-
Карты
-
Форматы
-
Нарисуем карту
-
Приложения и данные
-
Приложение В. Py в науке
-
Математика и статистика в стандартной библиотеке
-
Математические функции
-
Работа с комплексными числами
-
Рассчитываем точное значение чисел с плавающей точкой с помощью decimal
-
Выполняем вычисления для рациональных чисел с помощью модуля fractions
-
Используем Packed Sequences с помощью array
-
Обработка простой статистики с помощью модуля statistics
-
Перемножение матриц
-
Python для науки
-
NumPy
-
Создание массива с помощью функции array()
-
Создание массива с помощью функции arange()
-
Создание массива с помощью функций zeros(), ones() и random()
-
Изменяем форму массива с помощью метода reshape()
-
Получаем элемент с помощью конструкции []
-
Математика массивов
-
Линейная алгебра
-
Библиотека SciPy
-
Библиотека SciKit
-
Библиотека IPython
-
Лучший интерпретатор
-
Блокноты IPython
-
Pandas
-
Python и научные области
-
Приложение Г. Установка Python 3
-
Установка стандартной версии Python
-
Mac OS X
-
Windows
-
Linux или Unix
-
Установка Anaconda
-
***
-
Установка и использование pip и virtualenv
-
Установка и использование conda
-
Приложение Д. Ответы к упражнениям
-
Глава 1. Python: с чем его едят
-
Глава 2. Ингредиенты Python: числа, строки и переменные
-
Глава 3. Наполнение Python: списки, кортежи, словари и множества
-
Глава 4. Корочка Python: структуры кода
-
Глава 5. Py Boxes: модули, пакеты и программы
-
Глава 6. Ой-ой-ой: объекты и классы
-
Глава 7. Работаем с данными профессионально
-
***
-
Глава 8. Данные должны куда-то попадать
-
Глава 9. Распутываем Всемирную паутину
-
Глава 10. Системы
-
Глава 11. Конкуренция и сети
-
***
-
Приложение Е. Вспомогательные таблицы
-
Приоритет операторов
-
Строковые методы
-
Изменение регистра
-
Поиск
-
Изменение
-
Форматирование
-
Тип строки
-
Атрибуты модуля string
-
Примечания