Когда вы кодируете на других языках, вы иногда создаете область видимости блока, например:
statement
...
statement
{
statement
...
statement
}
statement
...
statement
Одна цель (из многих) - улучшить читаемость кода: показать, что определенные операторы образуют логическую единицу или что определенные локальные переменные используются только в этом блоке.
Есть ли идиоматический способ сделать то же самое в Python?
Модулями (и пакеты) является большой Pythonic способ разделить Вашу программу на отдельные пространства имен, которая, кажется, неявная цель этого вопроса. Действительно, поскольку я изучал основы Python, я чувствовал себя расстроенным отсутствием функции области действия блока. Однако, после того как я понял модули Python, я мог более изящно осознать свои предыдущие цели без потребности в области действия блока.
Как мотивация, и указать на людей к правильному направлению, я думаю, что полезно дать, обеспечивают явные примеры некоторых конструкций обзора Python. Сначала я объясняю свою неудачную попытку при использовании классов Python для реализации области действия блока. Затем я объясняю, как я достиг чего-то более полезное использование модули Python. В конце я обрисовываю в общих чертах практическое применение пакетов к загрузке и фильтрации данных.
В течение нескольких моментов я думал, что достиг области действия блока путем прикрепления кода в объявлении класса:
x = 5
class BlockScopeAttempt:
x = 10
print(x) # Output: 10
print(x) # Output: 5
, К сожалению, это ломается, когда функция определяется:
x = 5
class BlockScopeAttempt:
x = 10
print(x) # Output: 10
def printx2():
print(x)
printx2() # Output: 5!!!
That’s, потому что функции, определяемые в классе используют глобальную область видимости. Самое легкое (хотя не единственное) способ зафиксировать это должно явно указать класс:
x = 5
class BlockScopeAttempt:
x = 10
print(x) # Output: 10
def printx2():
print(BlockScopeAttempt.x) # Added class name
printx2() # Output: 10
Это не настолько изящно, потому что нужно записать функции по-другому в зависимости от того, содержал ли they’re в классе.
Модули очень похожи на статические классы, но модули являются намного более чистыми, по моему опыту. Чтобы сделать то же с модулями, я делаю файл названным my_module.py
в текущем рабочем каталоге со следующим содержанием:
x = 10
print(x) # (A)
def printx():
global x
print(x) # (B)
Затем в моем основном файле или интерактивный (например, Jupyter) сессия, я делаю
x = 5
import my_module # Output: 10 from (A)
my_module.printx() # Output: 10 from (B)
print(x) # Output: 5
Как объяснение, каждый файл Python определяет модуль, который имеет его собственное глобальное пространство имен. Импорт модуля позволяет Вам получать доступ к переменным в этом пространстве имен с .
синтаксис.
, Если Вы работаете с модулями на интерактивной сессии, можно выполнить эти две строки вначале
%load_ext autoreload
%autoreload 2
, и модули будут автоматически перезагружены, когда их соответствующие файлы будут изменены.
идея пакетов является небольшим расширением понятия модулей. Пакет является каталогом, содержащим (возможно пробел) __init__.py
файл, который выполняется на импорт. К модулям/пакетам в рамках этого каталога можно получить доступ с .
синтаксис.
Для анализа данных, я часто должен читать большой файл данных и затем в интерактивном режиме применять различные фильтры. Чтение файла занимает несколько минут, таким образом, я только хочу сделать это однажды. На основе того, что я узнал в школе об объектно-ориентированном программировании, я раньше полагал, что нужно написать код для фильтрации и загрузки как методы в классе. Главный недостаток этого подхода то, что, если я затем переопределяю свои фильтры, определение моих изменений класса, таким образом, я должен перезагрузить весь класс, включая данные.
В наше время с Python, я определяю пакет, названный my_data
, который содержит подмодули, названные load
и filter
. В filter.py
я могу сделать относительный импорт:
from .load import raw_data
, Если я изменяю filter.py
, затем autoreload
, обнаружит изменения. Это не перезагружает load.py
, таким образом, я не должен перезагружать свои данные. Таким образом, я могу моделировать свой код фильтрации в ноутбуке Jupyter, перенести его как функцию и затем вставку сокращения от моего ноутбука непосредственно в [1 118]. Понимание этого коренным образом изменило мой рабочий процесс и преобразовало меня от скептика стороннику “Zen Python. ”