greet_user.py
import json
filename = 'username.json'
with open(filename) as f_obj:
username = json.load(f_obj)
print("Welcome back, " + username + "!")
В точке вызов
json.load()
читает информацию из файла
username .json
в пере-
менную
username
. После того как данные будут успешно прочитаны, мы можем
поприветствовать пользователя по имени :
Welcome back, Eric!
Теперь эти две программы необходимо объединить в один файл. Когда пользова-
тель запускает
remember_me .py
, программа должна взять имя пользователя из памя-
ти, если это возможно; соответственно, программа начинается с блока
try
, который
пытается прочитать имя пользователя. Если файл
username .json
не существует,
блок
except
запросит имя пользователя и сохранит его в
username .json
на будущее:
remember_me.py
import json
# Программа загружает имя пользователя, если оно было сохранено ранее.
# В противном случае она запрашивает имя пользователя и сохраняет его.
filename = 'username.json'
try:
with open(filename) as f_obj:
username = json.load(f_obj)
except FileNotFoundError:
username = input("What is your name? ")
with open(filename, 'w') as f_obj:
json.dump(username, f_obj)
print("We'll remember you when you come back, " + username + "!")
else:
print("Welcome back, " + username + "!")
Никакого нового кода здесь нет; просто блоки кода из двух предыдущих приме-
ров были объединены в один файл. В точке программа пытается открыть файл
username .json
. Если файл существует, программа читает имя пользователя в па-
мять и выводит сообщение, приветствующее пользователя, в блоке
else
. Если
Сохранение данных 207
программа запускается впервые, то файл
username .json
не существует, и происходит
исключение
FileNotFoundError
. Python переходит к блоку
except
, в котором
пользователю предлагается ввести имя . Затем программа вызывает
json.dump()
для сохранения имени пользователя и выводит приветствие .
Какой бы блок ни выполнялся, результатом является имя пользователя и соот-
ветствующее сообщение. При первом запуске программы результат выглядит
так:
What is your name? Eric
We'll remember you when you come back, Eric!
Если же программа уже была выполнена хотя бы один раз, результат будет таким:
Welcome back, Eric!
Рефакторинг
Часто возникает типичная ситуация: код работает, но вы понимаете, что его струк-
туру можно усовершенствовать, разбив его на функции, каждая из которых ре-
шает свою конкретную задачу. Этот процесс называется рефакторингом (или
переработкой). Рефакторинг делает ваш код более чистым, понятным и простым
в расширении.
В процессе рефакторинга
remember_me .py
мы можем переместить основную часть
логики в одну или несколько функций. Основной задачей
remember_me .py
является
вывод приветствия для пользователя, поэтому весь существующий код будет пере-
мещен в функцию
greet_user()
:
remember_me.py
import json
def greet_user():
"""Приветствует пользователя по имени."""
filename = 'username.json'
try:
with open(filename) as f_obj:
username = json.load(f_obj)
except FileNotFoundError:
username = input("What is your name? ")
with open(filename, 'w') as f_obj:
json.dump(username, f_obj)
print("We'll remember you when you come back, " + username + "!")
else:
print("Welcome back, " + username + "!")
greet_user()
С переходом на функцию комментарии дополняются строкой документации, кото-
рая описывает работу кода в текущей версии . Код становится немного чище, но
функция
greet_user()
не только приветствует пользователя — она также загружает
хранимое имя пользователя, если оно существует, и запрашивает новое имя, если
оно не было сохранено ранее.
208 Глава 10 • Файлы и исключения
Переработаем функцию
greet_user()
, чтобы она не решала столько разных задач.
Начнем с перемещения кода загрузки хранимого имени пользователя в отдельную
функцию:
import json
def get_stored_username():
"""Получает хранимое имя пользователя, если оно существует."""
filename = 'username.json'
try:
with open(filename) as f_obj:
username = json.load(f_obj)
except FileNotFoundError:
return None
else:
return username
def greet_user():
"""Приветствует пользователя по имени."""
username = get_stored_username()
if username:
print("Welcome back, " + username + "!")
else:
username = input("What is your name? ")
filename = 'username.json'
with open(filename, 'w') as f_obj:
json.dump(username, f_obj)
print("We'll remember you when you come back, " + username + "!")
greet_user()
Новая функция
get_stored_username()
имеет четкое предназначение, изложенное
в строке документации . Эта функция читает и возвращает сохраненное имя
пользователя, если его удается найти. Если файл
username .json
не существует,
то функция возвращает
None
. И это правильно: функция должна возвращать
либо ожидаемое значение, либо
None
. Это позволяет провести простую проверку
возвращаемого значения функции. В точке программа выводит приветствие
для пользователя, если попытка получения имени пользователя была успешной;
в противном случае программа запрашивает новое имя пользователя.
Из функции
greet_user()
стоит вынести еще один блок кода. Если имя пользова-
теля не существует, то код запроса нового имени должен размещаться в функции,
специализирующейся на решении этой задачи:
import json
def get_stored_username():
"""Получает хранимое имя пользователя, если оно существует."""
...
def get_new_username():
"""Запрашивает новое имя пользователя."""
username = input("What is your name? ")
filename = 'username.json'
with open(filename, 'w') as f_obj:
json.dump(username, f_obj)
return username
Итоги 209
def greet_user():
"""Приветствует пользователя по имени."""
username = get_stored_username()
if username:
print("Welcome back, " + username + "!")
else:
username = get_new_username()
print("We'll remember you when you come back, " + username + "!")
greet_user()
Каждая функция в окончательной версии
remember_me .py
имеет четкое, конкретное
предназначение. Мы вызываем
greet_user()
, и эта функция выводит нужное при-
ветствие: либо для уже знакомого, либо для нового пользователя. Для этого функ-
ция вызывает функцию
get_stored_username()
, которая отвечает только за чтение
хранимого имени пользователя (если оно есть). Наконец, функция
greet_user()
при необходимости вызывает функцию
get_new_username()
, которая отвечает толь-
ко за получение нового имени пользователя и его сохранение. Такое «разделение
обязанностей» является важнейшим аспектом написания чистого кода, простого
в сопровождении и расширении.
Достарыңызбен бөлісу: |