Найти - Пользователи
Полная версия: Структура Flask проекта и Code Review.
Начало » Python для экспертов » Структура Flask проекта и Code Review.
1 2
4kpt_IV
Ну традицию постараемся не нарушать. Но в последнюю поездку тебе “незачет” и ты сам знаешь почему
ZZZ
Да… Это всё Светлов виноват!
Постараюсь исправится…
py.user.next
artexnet
Написал “для практики” простой парсер надуманно использовав парочку популярных фреймворков, при этом попытался учесть “расширяемость” проекта.
parsers.py
Умножь этот парсер на сто таких парсеров.
Как будешь гарантировать, что в них нет логических ошибок?
Как будешь вспоминать содержимое каждого парсера?
Как будешь исправлять в них ошибки?
Как будешь делать новые парсеры, похожие на существующие?
Как будешь их из веб переносить в систему?
Как будешь их менять при изменении html-кода?
artexnet
py.user.next
А Вы значит запоминаете логику всех приложений которые пишете?

Я не просил отлавливать логические ошибки в коде парсера, я это и сам могу, не хуже других. Умножать на сто..? Я не собираюсь плодить парсеры, у меня другой профиль, я вообще не понимаю почему Вы зациклились на этом слове. Можете просто проигнорировать этот файл. Это простой тестовый “проект”, в котором меня больше всего интересовал стиль написания на новом (пока что) для меня языке.

Если Вы имеете ввиду что этот код “вдруг” станет нерабочим, то согласен конечно. Я просто выбрал то что попалось под руку тогда. Значит придется “как-то” исправить, или вообще выбросить парсер и вставить что-то более долго-живущее.

P.S. Спасибо за то что просмотрели код.
artexnet
4kpt_IV
Спасибо за интересный разговор по теме.

Подскажите, пожалуйста, как можно закрыть тему?
py.user.next
artexnet
Я не просил отлавливать логические ошибки в коде парсера, я это и сам могу, не хуже других.
А я не отлавливал, я просто спросил, с чего ты взял, что одно мелкое изменение не сломает весь этот парсер?

artexnet
А Вы значит запоминаете логику всех приложений которые пишете?
Конечно. Но я не запоминаю, а код пишу так, чтобы потом читать его не более пяти минут. То есть я никогда не напишу функцию на три экрана, чтобы потом, прокурив её полчаса, строить в голове деревья со всеми ответвлениями для того, чтобы убедиться, что все её выходы обработаны.

В частности, при повреждении таблицы в источнике рейты будут неправильно заполнены, а ты даже об этом не узнаешь.
Вот эти три фрагмента, размазанные по всему коду, должны быть оттестированы по отдельности.
artexnet
for table_row in self.__g.doc.select('//table[@id="rb"]/tr'):
artexnet
for td in table_row.select('.//td'):
artexnet
self.rates[bank_logo_uri] = rate
Но они не могут быть протестированы, потому что скопом лежат в одной функции, к содержимому которой нет доступа.

models.py
artexnet
        return self.update_time.strftime('%d/%m/%Y %H:%M:%S') + ' - ' + \
            'USD[' + '{:.2f}'.format(self.usd_buying) + ": " + '{:.2f}'.format(self.usd_selling) + ']; ' + \
            'EUR[' + '{:.2f}'.format(self.eur_buying) + ": " + '{:.2f}'.format(self.eur_selling) + ']'
Надо использовать один вызов метода str.format(), а для времени в виде datetime есть свои спецификаторы форматирования, так что strftime() вообще не нужна. Да и конкатенация через плюсы не принята, нужно использовать str.join().

artexnet
Умножать на сто..? Я не собираюсь плодить парсеры
Да, умножать на сто. Здесь ты парсишь один сайт, а надо будет добавить сто сайтов с разным кодом и разными базами, где всё похоже, но немного отличается.

artexnet
Это простой тестовый “проект”, в котором меня больше всего интересовал стиль написания на новом (пока что) для меня языке.
Ну, прочитай pep8 тогда и Zen. Потому что ни того, ни другого в этом коде не наблюдается.

artexnet
Если Вы имеете ввиду что этот код “вдруг” станет нерабочим, то согласен конечно.
Я имею в виду юнит-тесты, что ты даже не можешь их написать, потому что свалил всё в одну функцию.

artexnet
Значит придется “как-то” исправить, или вообще выбросить парсер и вставить что-то более долго-живущее.
Ну да, и вставить то же самое (скорее, заново написать), которое проживёт точно так же - до первой звезды.
Rodegast
Ты путаешь атрибуты и атрибуты класса. Parser.banks и self.banks это абсолютно разные объекты.
banks = {}
# Rates map {banks_name: rate}
rates = {}
# Requests counter
number_of_requests = 0
def __init__(self):
    """Initializes a new instance of the class."""
    self.log.info('parser is started')
def get_rates(self):
    """Gets latest rates from target resource and stores in maps."""
    self.log.info('number of requests: %s' % self.number_of_requests)
    self.log.info('opening URL %s' % URL_EN)
    self.__g.go(URL_EN)
    self.log.info('done')
    self.banks = {}
    self.rates = {}
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB