Читаем Автостопом по Python полностью

Вы можете симулировать более привычное поведение, используя специальный синтаксис в выражении import: from modu import *. Однако это, как правило, считается признаком плохого тона: наличие конструкции import * усложняет чтение кода, делает зависимости более связанными и может затереть (перезаписать) существующие определенные объекты новыми описаниями из импортированного модуля.

Нотация from modu import func — это способ импортировать только необходимые вам атрибуты в глобальное пространство имен. Она гораздо безопаснее нотации from modu import *, поскольку явно показывает, что именно импортируется в глобальное пространство имен. Единственное ее преимущество перед более простой нотацией import modu в том, что она сэкономит вам немного времени.

В табл. 4.1 сравниваются разные способы импортирования определений из других модулей.

Таблица 4.1. Разные способы импортировать определения из модулей

Очень плохой код (непонятный для читателя)

Код получше (здесь понятно, какие имена находятся в глобальном пространстве имен)

Лучший код (сразу понятно, откуда появился тот или иной атрибут)

from modu import *

from modu import sqrt

import modu

x = sqrt(4)

x = sqrt(4)

x = modu.sqrt(4)

from modu import sqrt

from modu import sqrt

from modu import sqrt

Как упоминается в разделе «Стиль кода» в начале этой главы, читаемость — одна из основных особенностей Python. Читаемый код не содержит бесполезного текста. Но не следует максимально его сокращать в угоду краткости. Явно указывая, откуда появился тот или иной класс или функция, как в случае идиомы modu.func(), вы повышаете читаемость кода и степень его понимания.

Структура — это главное

Несмотря на то что вы можете структурировать проект так, как вам нравится, следует избегать некоторых ошибок.

Большое количество запутанных циклических зависимостей. Если для ваших классов Table и Chair из файла furn.py нужно импортировать класс Carpenter из файла workers.py (чтобы ответить на вопрос table.is_done_by() («произведены кем?»)) и если для класса Carpenter нужно импортировать классы Table и Chair (чтобы ответить на вопрос carpenter.what_do() («что производит?»)), у вас имеется циклическая зависимость: файл furn.py зависит от файла workers.py, который зависит от файла furn.py. В таком случае вам нужно использовать выражение import внутри методов, дабы избежать исключения ImportError.

Скрытое связывание. После каждого изменения в реализации класса Table вдруг перестают работать 20 несвязанных с ним тестов, поскольку это нарушает реализацию класса Carpenter. Это требует проведения аккуратных изменений для того, чтобы к ним адаптироваться, и означает, что в своем коде класса Carpenter вы делаете слишком много предположений о классе Table.

Избыточное использование глобального состояния или контекста. Вместо явной передачи данных (высота, ширина, тип, древесина) друг другу классы Table и Carpenter полагаются на глобальные переменные, которые модифицируются на лету разными агентами. Вам придется перебрать все объекты, имеющие доступ к этим глобальным переменным, чтобы понять, почему прямоугольный стол стал квадратным, и обнаружить, что это сделал код, который отвечает за работу шаблонов.

Спагетти-код. Вложенные условия if, расположенные на нескольких страницах подряд, и циклы for, содержащие большое количество скопированного

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

Равиоли-код. Такой код в Python встретить более вероятно, чем спагетти-код. Равиоли-код состоит из сотен небольших логических фрагментов, зачастую классов или объектов, которые не имеют хорошей структуры. Если вы не можете вспомнить, нужны ли вам для выполнения текущей задачи классы FurnitureTable, AssetTable, Table или даже TableNew, то, скорее всего, работаете с равиоли-кодом.

Упаковка

Python предоставляет довольно понятную систему упаковки, которая расширяет механизм модулей так, что он начинает работать с каталогами.

Любой каталог, содержащий файл __init__.py, считается пакетом Python. Каталог высшего уровня, в котором находится файл __init__.py, является корневым пакетом43. Разные модули пакетов импортируются аналогично простым модулям, но файл __init__.py при этом будет использован для сбора всех описаний на уровне пакета.

Перейти на страницу:

Похожие книги

100 знаменитых харьковчан
100 знаменитых харьковчан

Дмитрий Багалей и Александр Ахиезер, Николай Барабашов и Василий Каразин, Клавдия Шульженко и Ирина Бугримова, Людмила Гурченко и Любовь Малая, Владимир Крайнев и Антон Макаренко… Что объединяет этих людей — столь разных по роду деятельности, живущих в разные годы и в разных городах? Один факт — они так или иначе связаны с Харьковом.Выстраивать героев этой книги по принципу «кто знаменитее» — просто абсурдно. Главное — они любили и любят свой город и прославили его своими делами. Надеемся, что эти сто биографий помогут читателю почувствовать ритм жизни этого города, узнать больше о его истории, просто понять его. Тем более что в книгу вошли и очерки о харьковчанах, имена которых сейчас на слуху у всех горожан, — об Арсене Авакове, Владимире Шумилкине, Александре Фельдмане. Эти люди создают сегодняшнюю историю Харькова.Как знать, возможно, прочитав эту книгу, кто-то испытает чувство гордости за своих знаменитых земляков и посмотрит на Харьков другими глазами.

Владислав Леонидович Карнацевич

Неотсортированное / Энциклопедии / Словари и Энциклопедии