Попытка рефакторинга кода для сайта stati c с использованием python - PullRequest
0 голосов
/ 23 марта 2020

Я сейчас делаю задание для класса. Он включает в себя рефакторинг python кода для генерации страниц c сайта. Я нахожусь в фазе, где я пытаюсь реорганизовать код для моего генератора сайта, и он включает в себя для l oop, который делает шаблон сайта. Мой инструктор говорит мне, что я должен удалить некоторые повторяющиеся строки и заменить их одной копией для l oop. Я был бы очень признателен за помощь в этом, поскольку я занимаюсь этим впервые. Я распознаю повторяющиеся экземпляры, но не знаю, как правильно структурировать их в коде.

Вот мой код:

def main():
    print('building static site')
    top_html = open('templates/top.html').read()
    bottom_html = open('templates/bottom.html').read()
    middle_html = open('content/index.html').read()
    combined_html = top_html + middle_html + bottom_html
    open('docs/index.html', 'w+').write(combined_html)

    print('building static site')
    top_html = open('templates/top.html').read()
    bottom_html = open('templates/bottom.html').read()
    middle_html = open('content/projects.html').read()
    combined_html = top_html + middle_html + bottom_html
    open('docs/projects.html', 'w+').write(combined_html)

    print('building static site')
    top_html = open('templates/top.html').read()
    bottom_html = open('templates/bottom.html').read()
    middle_html = open('content/contact.html').read()
    combined_html = top_html + middle_html + bottom_html
    open('docs/contact.html', 'w+').write(combined_html)

    for page in pages:
        filename = page['filename']
        print('the filename that we want to read in:', filename)
main()

1 Ответ

0 голосов
/ 23 марта 2020

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

print('building static site')
top_html = open('templates/top.html').read()
bottom_html = open('templates/bottom.html').read()
middle_html = open('content/projects.html').read()
combined_html = top_html + middle_html + bottom_html
open('docs/projects.html', 'w+').write(combined_html)

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

def build_site(file_name):
    print('building static site')
    top_html = open('templates/top.html').read()
    bottom_html = open('templates/bottom.html').read()
    middle_html = open(f'content/{file_name}').read()
    combined_html = top_html + middle_html + bottom_html
    open(f'docs/{file_name}', 'w+').write(combined_html)

Уведомление что projects.html было заменено на file_name, которое мы передаем в функцию.

Это делает основную функцию go ниже:

def main():
    build_site('index.html')
    build_site('projects.html')
    build_site('contact.html')

    for page in pages:
        filename = page['filename']
        print('the filename that we want to read in:', filename)

Все сайты, которые мы здесь создаем, заканчиваются .html. Мы могли бы поместить это в функцию build_site(), но это ограничивает ваши каталоги только файлами, заканчивающимися .html. Чтобы сделать шаг go дальше, мы могли бы теперь использовать все oop для каждой из различных страниц.

def main():
    for site_name in ('index', 'projects', 'contact'):
        build_site(f'{site_name}.html')
    for page in pages:
        filename = page['filename']
        print('the filename that we want to read in:', filename)

Дальнейшие улучшения

Вот некоторые дополнительные улучшения, которые я хотел бы сделать ,

  1. Когда вы делаете open(...).read(), вам не удается закрыть файл, поэтому он просто зависает, пока не будет очищен. Вы можете создать новую функцию для этого, используя менеджер контекста , чтобы файл автоматически закрывался.
def read_content(file_path):
    with open(file_path) as f:
        return f.read()

Затем измените build_site на:

top_html = read_content('templates/top.html')
bottom_html = read_content('templates/bottom.html')
middle_html = read_content('content/projects.html')

Я бы сделал то же самое для записи файла, но поскольку это происходит только один раз, я бы не стал создавать функцию.

...
with open(f'docs/{file_name}', 'w+') as f:
    f.write(combined_html)
...
Я бы поместил оператор print вне функции (но внутри для l oop), так как я не люблю печатать вещи в функциях, которые делают вещи. Я также заставил бы это распечатать то, что строилось.
# delete print(...) in build_site(file_name)
# then

def main():
    for site_name in ('index', 'projects', 'contact'):
        print(f'Building static site: {site_name}')
        build_site(f'{site_name}.html')
    ...
...