Пресс-центр
Соблюдая высокие стандарты публичной работы, ПЕТОН сотрудничает со средствами массовой информации (СМИ). ПЕТОН при взаимодействии со СМИ руководствуется принципами открытости, оперативности и полноты предоставления информации. Помимо этого, мы постоянно информируем общественность о проектах и событиях, которые происходят в холдинге, в том числе спонсорских, благотворительных и образовательных проектах на территории республики Башкортостан и других регионах присутствия ПЕТОН.
Контакты для СМИ
PR-руководитель
+7 (347) 246-87-09, доб. 2724
Новости СМИ о нас Видео
СМИ о нас
4 августа 2022
28 июля 2022
28 июля 2022
21 июля 2022
15 июля 2022
11 июля 2022
27 июня 2022
24 июня 2022
30 мая 202227 мая 2022
27 мая 2022
26 мая 2022
16 мая 2022
20 апреля 2022
15 апреля 2022
21 марта 2022
14 марта 2022
16 февраля 2022
15 февраля 2022
11 февраля 2022
8 февраля 2022
27 января 202214 декабря 2021
22 ноября 2021
22 ноября 2021
18 ноября 2021
22 октября 2021
18 октября 2021
21 сентября 2021
15 сентября 2021
9 сентября 2021
6 августа 2021
5 августа 2021
12 июля 2021
9 июля 20218 июля 2021
30 июня 2021
30 июня 2021
23 июня 2021
7 июня 2021
3 июня 2021
27 мая 2021
19 мая 2021
17 мая 2021
12 мая 2021
28 января 2021
25 декабря 2020
28 июля 2020
28 июля 2020
27 июля 20201 июля 2020
25 июля 2019
22 апреля 2019
22 октября 2018
2 октября 2018
3 сентября 2018
23 мая 2018
9 апреля 2018
26 марта 2018
28 февраля 2018
14 февраля 2018
13 февраля 2018
13 февраля 201825 декабря 2017
21 декабря 2017
1 декабря 2017
30 ноября 2017
29 ноября 2017
28 ноября 2017
1 сентября 2017
28 июня 2017
3 марта 2017
21 февраля 2017
2 декабря 2016
1 ноября 2016
29 сентября 2016
30 августа 2016
8 августа 2016
13 октября 2015
16 октября 2014
14 марта 2014
показать еще
Соблюдая высокие стандарты публичной работы, ПЕТОН сотрудничает со средствами массовой информации (СМИ). ПЕТОН при взаимодействии со СМИ руководствуется принципами открытости, оперативности и полноты предоставления информации. Помимо этого, мы постоянно информируем общественность о проектах и событиях, которые происходят в холдинге, в том числе спонсорских, благотворительных и образовательных проектах на территории республики Башкортостан и других регионах присутствия ПЕТОН.
Путеводитель по Python. Пишем великолепный код / Хабр
Доброго времени суток, Хабрахабр. Сегодня на крыле принес еще один перевод я (pdf-ки гугловского стайл гайда выложены). Хотя, кто знает, если кто-то оценит сию работу — быть может появится и продолжение. Как-то днём одним, предложил мне мой широко известный в узких кругах коллега scraplesh почитать ресурс — The Hitchhiker’s Guide to Python! называемый. Ресурс этот понравился мне. Понравились советы выдаваемые там. Понравилась канва повествования и вообще понравилось направление мысли автора. А если что-то хорошо на Ваш вкус, то нужно передавать это из уст в уста:) Итак, решил я сделать перевод данного ресурса. Но не всё так сразу — сначала будет пробная статья «на отклик» хабрасообщества. Если уважаемым гикам понравится сия тематика и изложение — будем стараться выпускать новые части. На первый «отклик» я выбрал раздел — «Writing Great Code» и в нем два подпункта «Structure is Key» и «Modules». Откликнемся под катом.
Но перед тем, как окунуться с головой в чужие мысли относительно любимого Python, нужно представить собственно автора ресурса. Зовут его Kenneth Reitz. Как я понял по собранной информации — он профессиональный фотограф (об этом мы можем узнать на его личном сайте), евангелист языка Python и просто гуру разного рода разработки. Работает он на данный момент (по неподтвержденным данным) в Heroku. Так же перепризываю всех форкать его проект на гитхаб.
Фотография Кеннета
Kenneth Reitz на PyCon в Австралии (2012)
Далее — собственно сама статья. (При обнаружении ошибок, как водится — сразу кричите о них! Ошибки требуют исправления.)
Структурируйте свой проект
Под структурой мы подразумеваем решения, которые Вы приняли в отношении того, как Ваш проект сможет достичь поставленных целей. Мы должны рассмотреть как лучше использовать функциональные особенности языка Python, чтобы писать чистый и эффективный код. С практической точки зрения, понятие «структура» означает создание (написание) чистого когда в котором, логика и зависимости так же ясны как организация файлов и папок в файловой системе.
Какие функции должны быть перемещены в какие модули? Как пойдет поток данных через проект? Какие особенности и функции могут быть сгруппированы вместе и изолированы? Отвечая на подобные вопросы, Вы можете начать планировать как будет выглядеть готовый продукт.
В данном разделе мы внимательнее посмотрим на систему модулей и импортов в Python, т.к. они являются центральным элементом в обеспечении структурирования Вашего проекта. Затем, мы обсудим различные точки зрения о том, как построить код, который может быть расширен и надежно протестирован.
Структура решает
Благодаря тому, что импорты и модули обрабатываются в Python, сравнительно просто структурировать проект написанный на этом языке. Слово «просто», в данном контексте означает, что Вы не будете создавать лишних ограничений, и то, что модель импортируемого модуля легко понять. Таким образом, Вам остается сконцентрироваться на чисто архитектурной задаче, а именно трудиться над созданием различных частей Вашего проекта и их взаимодействии.
Просто структурированный проект — означает, что также просто можно создать и плохо структурированный проект. Некоторые признаки плохо структурированного проекта:
- Множественные и грязные циклические зависимости. Если Ваши классы
Table
иChair
нуждаются в импорте классаCarpenter
из модуляworkers.py
, для того, чтобы ответить на вопросtable. isdoneby()
, и наоборот, если классCarpenter
нуждается в импорте классаTable
и классаChair
, чтобы ответить на вопросcarpenter.whatdo()
— Вы получаете циклическую зависимость. В этом случае Вам придется прибегнуть к хитрым уловкам, таким как использование оператора импорта внутри методов или функций. - Скрытые связи. Все и каждое изменение в классе
Table
проваливает 20 тестов в несвязанных тестах, т.к. оно извращает выполнение кода классаCarpenter
, который требует хирургически тонкого адаптивного изменения кода. Это означает, что у Вас слишком много «договоренностей» относительно класса Table в коде классаCarpenter
или наоборот. - Интенсивное использование глобального пространства имен или контекста. Вместо явной передачи (высота, ширина, тип, дерево) друг другу переменных классами
Table
иCarpenter
, Вы полагаетесь на глобальные переменные, которые могут быть изменены и модифицированы на лету разными «товарищами». Вы должны внимательно изучить все места, откуда можно получить доступ к этим глобальным переменным, чтобы понять, почему прямоугольный стол стал квадратным и обнаружить, что удаленный код так же подвергся изменению в данном контексте, подменив размеры стола. - Спагетти-код. Несколько страниц вложенных друг в друга конструкций
if
и цикловfor
с большим количеством повторяющегося кода и вообще не сегментированного, известного как спагетти, кода. Благодаря значащим отступам в Python (одной из самых обсуждаемых особенностей), очень сложно писать такой код на данном языке. Так что есть хорошие новости — Вы не будете наблюдать такой код часто. - Равиоли-код. Такой код более типичен для Python. Он состоит из сотен одинаковых (или подобных друг другу) кусочков логики, классов или объектов без надлежащей структуризации. Если Вы никак не можете запомнить не использовать
FurnitureTable
,AssetTable
илиTable
, или дажеTableNew
для решения Вашей задачи — Вы будете купаться в равиоли-коде.
Модули
Модули в Python являются одним из основных слоев абстракции которые доступны, и, вероятно, являются наиболее нативными для языка. Уровни абстракции позволяют разделить код на части обрабатывающие соответствующие данные и содержащие какой-либо функционал.
Например, один слой проекта может обрабатывать взаимодействие с пользователем, в то время как другой будет обрабатывать манипулирование данными на низком уровне. Наиболее естественный способ разделить эти два уровня — это поместить всю функциональность в один файл, а все низкоуровневые операции в другой. В таком случае интерфейсный файл будет нуждаться в импорте файла с низкоуровневым функционалом. Это делается с помощью выражений import
и from ... import
.
Как только Вы начинаете использовать выражение import — Вы начинаете использовать модули. Это могут быть встроенные модули, такие как os
и sys
, сторонние модули, которые Вы установили в свою среду, или внутренние модули Вашего проекта.
Чтобы придерживаться стиля руководства, старайтесь давать модулям короткие имена, содержащие только буквы нижнего регистра и уверяться, что Вы не используете специальные символы, такие как точка (.) или знак вопроса (?). Так как имя файла подобное my.spam.py, Вы должны избегать. Именование таким образом будет мешать Python искать модули.
В данном примере Python ожидает найти «spam.py
» в папке по имени «my
«, которой не существует. Существует пример того, как точечная нотация должна быть использована в документах Python.
Если Вы хотите, Вы можете назвать файл my_spam.py
, но даже нашего друга — Подчеркивание — не стоит часто использовать в именах модулей.
Помимо некоторых ограничений именования, ничего больше не требуется файлу чтобы стать Python-модулем, но механизм импорта необходимо понимать для того, чтобы использовать эту концепцию должным образом и избежать некоторых проблем.
Откровенно говоря, оператор импорта будет искать соответствующий файл module. py в той же директории, где находится импортирующий файл. Если он не будет найден, интерпретатор Python будет искать module.py
в переменной «path
» рекурсивно и возбудит исключение ImportError
, если последний не будет найден.
После того, как module.py
будет найден, интерпретатор Python выполнит модуль в изолированной области видимости. Любое объявление верхнего уровня в файле module.py
будет выполнено, включая вложенные импорты, если таковые имеются. Объявления функций и классов сохранятся в словарь модуля.
Затем переменные модуля, функции и классы будут доступны для вызова через пространство имен модуля — центральное понятие в программировании, которое особенно мощно и полезно в языке Python.
Во многих языках, файл включается напрямую используя препроцессор чтобы найти весь код в файле и «скопировать» его в код вызывающего модуля. Это отличается от поведения языка Python, в котором подключаемый код изолирован в области видимости своего модуля, что означает, что Вы можете не беспокоиться о том, что включение кода может иметь нежелательные последствия, например, переопределение существующих функций с тем же именем.
Это позволяет моделировать более стандартное поведение с помощью специального синтаксиса выражения import: from module import *
. Обычно это считается плохой практикой. Использование «import *
» делает код трудным для чтения и делает зависимости менее разобщенными.
Использование from module import func
это способ точно указать функцию, которую вы хотите импортировать и поместить в глобальную область видимости. А так же это менее вредно для кода нежели «import *
«, т.к. тут ясно видно что импортируется в глобальную область видимости, преимущество более простой записи import module заключается в экономии нажатий клавиш.
# Very bad [...] from modu import * [...] x = sqrt(4) # Is sqrt part of modu? A builtin? Defined above? # Better from modu import sqrt [...] x = sqrt(4) # sqrt may be part of modu, if not redefined in between # Best import modu [...] x = modu.sqrt(4) # sqrt is visibly part of modu's namespace
Как указано в разделе о стиле, читаемость является одной из главных особенностей Python. Читаемость означает уход от использования бесполезного текстового наполнения и беспорядка в коде, поэтому обычно некоторые усилия тратятся на попытки достичь определенного уровня краткости кода. Но лаконичность и простота имеют определенные пределы, где сокращение кода должно прекратиться. Будучи в состоянии сразу сказать где начинается тот или иной класс или функция, как и идеология module.func
, которая значительно улучшает читаемость кода и его прозрачность во всех, кроме самых простых, отдельных стоящий проектов «в одном файле».
Тестовая организация в Python — pythobyte.com
Сейчас в течение некоторого времени Python был моим хакерским языком и языком концепции по выбору.
Таким образом, тестирование в Python никогда не было для меня важной проблемой, потому что я бы не стал использовать код в производстве или даже вернуться к нему большую часть времени.
Недавно я писал небольшое приложение Flask в Python, чтобы калибровать и непрерывно Читать из нагрузочной ячейки HX711 с Raspberry Pi Zero W Анкет
Поскольку я использую этот код в рамках моей диссертации бакалавра, я считаю, что он является «производственным» кодом, и, что наиболее важно, я хочу, чтобы его было легко рефакторировать и расширить.
Так что впервые мне пришлось подумать о тестировании на Python.
Настройка
Перво -наперво, мой проект без тестов выглядит так:
Как видите, это очень простая настройка с 2 модулями Бэкэнд и Сервис и точка входа Server.py
Анкет
Цель
Для легкого тестирования я хочу иметь возможность определять тесты для каждого модуля и иметь возможность запускать их отдельно, а также простой способ запуска всех тестов всех модулей.
Решение
Для тестирования я буду использовать Pythons Unittest
модуль. Самая маленькая единица для тестирования с Unittest – это Testcase
которые могут иметь 1 или более методов формы def Test _*():
Анкет
Для начала я попытался разделить различные обязанности моих модулей на Testcase
классы, например:
import unittest class TestCalibrationChecks(unittest. TestCase): """ methods that test whether all checks on the calibration state of the scale work """ class TestCalibrationProcess(unittest.TestCase): """ methods that test calibration of the scale """
После написания тестовых случаев для модулей мой проект выглядел так:
Запуск TestCase из корневого проекта выглядит следующим образом: python -m Unittest Backend.test.calibration_test. ТЕСТИКАКАЯ КАЛИБРИИКА
Теперь я хотел иметь возможность запустить все тесты в каждом модуле, поэтому я осмотрел вокруг Документы и пришел в Unittest’s TestSuite
Анкет
A TestSuite
это коллекция Испытательные шкалы и/или Проверки и может использоваться для группирования тестов вместе.
Итак, в корне моих модулей я написал файл tests.py
Чтобы объединить все тестовые шкафы из этого модуля тест
Папка в один набор. Для бэкэнд -модуля это выглядело так:
import unittest from backend. test import TestCalibrationChecks from backend.test import TestCalibrationProcess from backend.test import TestSystemHealthChecks def test_scale_suite(): scale_test_suite = unittest.TestSuite([ unittest.TestLoader().loadTestsFromTestCase(TestCalibrationChecks), unittest.TestLoader().loadTestsFromTestCase(TestCalibrationProcess), unittest.TestLoader().loadTestsFromTestCase(TestSystemHealthChecks) ]) result = unittest.TestResult() runner = unittest.TextTestRunner() print(runner.run(scale_test_suite)) if __name__ == '__main__': test_scale_suite()
После написания такого файла для каждого модуля мой проект выглядел так:
Теперь я смог запустить тесты для каждого модуля из корня проекта с такой командой, как это: Python -m Unittest Backend.tests
Анкет
Но Как насчет запуска всех тестов из всех модулей с помощью одной команды?
С крошечным рефактором Backend/tests. py
и Service/tests.py
Я смог написать tests.py
В корневом каталоге и объедините Бэкэнд и Сервис Проверьте люксы на более крупный Тестирование
Сначала я изменил tests.py
В каждом модуле, чтобы TestSuite
не создается в функции, но является экспортируемой переменной:
import unittest from backend.test import TestCalibrationChecks from backend.test import TestCalibrationProcess from backend.test import TestSystemHealthChecks scale_test_suite = unittest.TestSuite([ unittest.TestLoader().loadTestsFromTestCase(TestCalibrationChecks), unittest. TestLoader().loadTestsFromTestCase(TestCalibrationProcess), unittest.TestLoader().loadTestsFromTestCase(TestSystemHealthChecks) ]) def test_scale_suite(): result = unittest.TestResult() runner = unittest.TextTestRunner() print(runner.run(scale_test_suite)) if __name__ == '__main__': test_scale_suite()
Теперь я смог определить tests.py
в проекте корень как это:
import unittest from backend import tests as backend_tests from service import tests as service_tests complete_test_suite = unittest.TestSuite([ backend_tests.scale_test_suite, service_tests. service_test_suite ]) def run_all_suites(): result = unittest.TestResult() runner = unittest.TextTestRunner() print(runner.run(complete_test_suite)) if __name__ == '__main__': run_all_suites()
Готовый проект теперь выглядит так:
И из корня проекта я могу запустить
- Все тесты
Python -m тесты
- Бэкэнд -тесты
питон -М Unittest Backend.tests
- Сервисные тесты
Python -m Unittest Service.tests
Миссия выполнена
Примечания
- Я знаю, что есть функция
модульный тест. TestLoader (). Discover ()
который автоматически обнаружит все испытательные шкафы в дереве файлов. Я решил не использовать его, потому что мне нравится явно заявлять, что запустить, чтобы я мог видеть, чего ожидать, и избегать некоторых тестов, не выполняющихся, потому что искатель по какой -то причине пропустил их. - Я не говорю, что это правильный способ организовать ваши тесты в Python, кажется, что мне просто очень хорошо работает. Рад слышать ваши комментарии по этому поводу:)
Оригинал: “https://dev.to/danielw/test-organization-in-python-14kk”
ООО ЧАСТНАЯ ОХРАННАЯ ОРГАНИЗАЦИЯ «ПИТОН», ст-ца Динская, ИНН 2330023507, контакты, реквизиты, финансовая отчётность и выписка из ЕГРЮЛ
+7 861 625-23-36
—
Контактная информация неактуальна?
Редактировать
Юридический адрес
353204, Краснодарский край, Динской район, ст-ца Динская, ул. Промышленная, д. 3
Показать на картеОГРН | 1022303618655 |
ИНН | 2330023507 |
КПП | 233001001 |
ОКПО | 44812360 |
Код ОКОГУ | 4210014 Организации, учрежденные юридическими лицами или гражданами, или юридическими лицами и гражданами совместно |
Код ОКОПФ | 12300 Общества с ограниченной ответственностью |
Код ОКФС | 16 Частная собственность |
Код ОКАТО | 03214804001 ст-ца Динская |
Код ОКТМО | 03614404101 ст-ца Динская |
Регистрация в ФНС
Регистрационный номер 1022303618655 от 9 декабря 2002 года
Межрайонная инспекция Федеральной налоговой службы №16 по Краснодарскому краю
Регистрация в ПФР
Регистрационный номер 033032006105 от 11 октября 1996 года
Управление Пенсионного фонда РФ в Динском районе Краснодарского края
Регистрация в ФСС
Регистрационный номер 231446090823141 от 17 мая 2001 года
Филиал №14 Государственного учреждения — Краснодарского регионального отделения Фонда социального страхования Российской Федерации
Ветров Константин Павлович ИНН 550520582103 с 20. 05.2015 | 100% |
80.10 | Деятельность охранных служб, в том числе частныхОСНОВНОЙ |
80.30 | Деятельность по расследованию |
80.20 | Деятельность систем обеспечения безопасности |
Финансовая отчётность ООО ЧОО «ПИТОН» согласно данным ФНС и Росстата за 2013–2021 годы
Финансовые результаты за 2021 год
Выручка | Чистая прибыль | Капитал |
---|---|---|
16,3 млн ₽ 2% | 506 тыс. ₽ 26% | 46,5 млн ₽ 2% |
Показатели финансового состояния за 2021 год
- Коэффициент автономии (финансовой независимости) 1. 00
- Коэффициент обеспеченности собственными оборотными средствами —
- Коэффициент покрытия инвестиций 1.00
- Коэффициент текущей ликвидности —
- Коэффициент быстрой ликвидности —
- Коэффициент абсолютной ликвидности —
- Рентабельность продаж 3. 1%
- Рентабельность активов 1.1%
- Рентабельность собственного капитала 1.1%
Уплаченные ООО ЧОО «ПИТОН» – ИНН 2330023507 – налоги и сборы за 2020 год
Страховые и другие взносы на обязательное пенсионное страхование, зачисляемые в Пенсионный фонд Российской Федерации | 2,3 млн ₽ |
Страховые взносы на обязательное медицинское страхование работающего населения, зачисляемые в бюджет Федерального фонда обязательного медицинского страхования | 630,4 тыс. ₽ |
Налог на имущество организаций | 19,6 тыс. ₽ |
Налог, взимаемый в связи с применением упрощенной системы налогообложения | 34 тыс. ₽ |
Страховые взносы на обязательное социальное страхование на случай временной нетрудоспособности и в связи с материнством | 140,4 тыс. ₽ |
Итого | 3,1 млн ₽ |
Имелись незначительные задолженности по пеням и штрафам за предыдущий отчётный период
Налог на доходы физических лиц | 12,1 ₽ |
Итого | 12,2 ₽ |
Согласно данным ФНС, среднесписочная численность работников за 2021 год составляет
50 человек
2020 г. | 52 человека | 19,8 тыс. ₽ |
2019 г. | 49 человек | 21,2 тыс. ₽ |
Значения рассчитаны автоматически по сведениям о взносах в фонд обязательного медицинского страхования и среднесписочной численности ООО ЧОО «ПИТОН», эта информация может быть неточной
Согласно данным ЕГРЮЛ от ФНС, ООО ЧОО «ПИТОН» имеет 1 лицензию
Частная охранная деятельность | 1 |
Компания ООО ЧОО «ПИТОН» опубликовала 1 сообщение на Федресурсе
Уменьшение уставного капитала | 1 |
Согласно данным ФГИС «Единый Реестр Проверок», с 2015 года в отношении ООО ЧОО «ПИТОН» были инициированы 4 проверки
3 | без нарушений |
1 | выявлены нарушения |
0 | результатов ещё нет |
Последняя проверка
Плановая документарная и выездная проверка № 231901526172 от 4 февраля 2019 года
Проверку проводит Главное управление Федеральной службы войск национальной гвардии Российской Федерации по Краснодарскому краю
Выявлены нарушения
Полная хронология важных событий с 3 октября 1996 года
30. 03.2020 Сдана финансовая отчётность за 2019 год | |
13.03.2021 Юридический адрес изменен с 353204, Краснодарский край, Динской район, станица Динская, ул. Промышленная, д. 3 на 353204, Краснодарский край, Динской район, ст-ца Динская, ул. Промышленная, д. 3 | |
24.03.2021 Сдана финансовая отчётность за 2020 год | |
29.03.2021 Уставный капитал повышен с 252 500 ₽ до 500 000 ₽ | |
20.07.2021 Юридическое лицо находится в процессе уменьшения уставного капитала | |
26.01.2022 Юридическое лицо снова является действующим | |
Уставный капитал понижен с 500 000 ₽ до 250 000 ₽ | |
25.03.2022 Сдана финансовая отчётность за 2021 год |
Похожие компании
ООО «ОО «ИНСАР» г. Кировск, Ленинградская область | 4723002712 |
ООО ЧОО «ЛЕГИОН-2012» г. Махачкала, Республика Дагестан | 0549009549 |
ООО ОФ»ЕНИСЕЙ» г. Красноярск, Красноярский край | 2465206255 |
ООО ЧОП «УРАЛ ДЕРЖАВА» г. Челябинск, Челябинская область | 7415094094 |
ООО «ЧОО «ЭСКОРТ» г. Череповец, Вологодская область | 3528078466 |
ООО ОП «ВЯЧЕСЛАВ» г. Самара, Самарская область | 6311176985 |
ООО ЧОП «МИБ-ЗАЩИТА» г. Москва | 7725591113 |
Новости
НовостиИскать по названию:
Международное сотрудничество Молодежная политика Наука Наука и образование Новости Министерства Образование
Искать по дате:
2020 2021 2022
сбросить фильтр
29
сентября
В Крыму завершился Летний многопрофильный университет «Россия — Африка»
Врачи из африканских стран успешно прошли курсы повышения квалификации в Крымском федеральном университете (КФУ) им. В. И. Вернадского в рамках Летнего многопрофильного университета «Россия — Африка». Проект был запущен участниками консорциума РАФУ (Российско-Африканский сетевой университет) при поддержке Минобрнауки России.
Международное сотрудничество
29
сентября
В Москве прошло 35-е заседание Совета Международной ассоциации академий наук
26–28 сентября на базе Национального исследовательского центра «Курчатовский институт» и Московского государственного университета (МГУ) им. М. В. Ломоносова проведено 35-е заседание Совета Международной ассоциации академий наук (МААН) под председательством Национальной академии наук Республики Беларусь и при активной поддержке Российской академии наук (РАН).
Международное сотрудничество
29
сентября
Ученые построили таблицу Менделеева для систематизации элементов генетического кода
Российские исследователи создали таблицу генетического кода, взяв за основу периодическую систему химических элементов Дмитрия Менделеева. Разработка позволит конструировать новые типы биополимеров (высокомолекулярных веществ, входящих в состав живых организмов), например белков с заданными свойствами, которые будут востребованы в технике, фармакологии и других отраслях экономики. Работа выполнена специалистами подведомственного Минобрнауки России Санкт-Петербургского государственного электротехнического университета (СПбГЭТУ) «ЛЭТИ».
Наука
29
сентября
Глава Минобрнауки России вошел в состав организационного комитета по проведению Года педагога и наставника
Председатель Правительства РФ Михаил Мишустин утвердил состав организационного комитета по проведению Года педагога и наставника. В комитет вошел глава Минобрнауки России Валерий Фальков.
Новости Министерства
29
сентября
Проект закона Минобрнауки России о запрете краткосрочных контрактов в вузах внесен в Правительство Российской Федерации
В случае принятия законопроекта вузы будут обязаны оформлять трудовые договоры с преподавателями либо на неопределенный срок, либо на срок избрания на должность. Соответствующие изменения в Трудовой кодекс, разработанные Минобрнауки России, направленны на защиту прав работников высшей школы.
Новости Министерства
29
сентября
Осталось пять дней до конца подачи заявок на VIII Всероссийскую премию «За верность науке»
Прием заявок на VIII Всероссийскую премию «За верность науке» проходит на сайте до 3 октября включительно. Победители получат денежные призы, а также специальные призы от партнеров конкурса: путешествие на атомном ледоколе, поездку на один из российских космодромов или экскурсию на вертолетный завод в Казани. Премия проводится в рамках объявленного Президентом России Владимиром Путиным Десятилетия науки и технологий.
Новости Министерства
29
сентября
Коллектив ученых из стран БРИКС разрабатывает съедобную экологичную пленку, которая продлит срок годности продуктов
К созданию инновационной упаковки для продуктов — биоразлагаемой пленки из органических отходов — приступил коллектив ученых из России, Бразилии, Индии и ЮАР. Поддержанная грантом Минобрнауки России разработка направлена на защиту еды от воздействия патогенных микроорганизмов, послужит индикатором свежести пищи и снизит уровень загрязнения окружающей среды.
Международное сотрудничество
29
сентября
Изучение метеорита из Африки раскрыло подробности богатой событиями эволюции астероидов
В пустыне Сахара был обнаружен каменный метеорит весом всего 4,5 г. Оказалось, что он образовался при плавлении вещества L-хондритового астероида 470 млн лет назад в результате катастрофического столкновения с другим крупным астероидом главного пояса. Это событие было настолько крупномасштабным, что многие обломки, выброшенные с астероида при ударе, достигли Земли и были захоронены в осадочных породах ордовикского периода, в которых обнаруживаются до сих пор. Исследование метеорита показало, что после этого события родительский астероид сталкивался с небольшими телами еще несколько раз, включая столкновение с ледяным астероидом или кометой.
Наука
29
сентября
Томский ученый создал уникальный 3D эндопротез плечевого сустава с противовоспалительными и противоопухолевыми свойствами
Имплантат плечевого сустава с модифицированной поверхностью разработал ученый НИИ онкологии подведомственного Минобрнауки России Томского национального исследовательского медицинского центра Российской академии наук (НИМЦ), кандидат медицинских наук Илья Анисеня совместно с компаниями-партнерами. Уникальный эндопротез из биосовместимого титанового сплава надежно крепится и сохраняет подвижность сустава, предотвращая вывихи. Операции по его установке проводятся в клинике медицинского центра.
Наука
ПИТОН, Курган — Частная охранная организация на Красина, 41 на «Справке РУ» — телефоны, карта, фото, отзывы и оценки клиентов
Частная охранная организация в Кургане
Открыто Сейчас открыто
QR-код
- Подробнее
Оценка:
Телефон:
- +7 (352) 245-52-76
Факс:
- +7 (352) 241-65-78
E-mail:
- piton@tp. kurgan.ru
Адрес:
г. Курган, Красина, 41
Индекс:
640000
Регион:
Россия, Курганская область
Сайт:
- Tp-piton.kurgan.ru
Категория:
Услуги охранных организаций в Кургане
Часы работы:
Пн 00:00 — 24:00 | Вт 00:00 — 24:00 | Ср 00:00 — 24:00 | Чт 00:00 — 24:00 | Пт 00:00 — 24:00 | Сб 00:00 — 24:00 | Вс 00:00 — 24:00 |
---|
QR-код с информацией о компании
- Контакты
- Карта
- О компании
- Похожие
- Отзывы
- Скачать PDF
- Распечатать
- Обнаружили ошибку?
- Это ваша компания?
-
Карта проезда
-
Фотографии
На данный момент не добавлено ни одной фотографии компании.
-
О компании
Частная охранная организация “Питон” работает в сфере ”Услуги охранных организаций”. На карте Кургана вы можете увидеть улицу и здание по адресу: Курган, Красина, 41. . Каждый дозвон по телефону +7 (3522) 45-52-76 помогает поддерживать точность и правильность информации о данном предприятии.
-
Возможно, вас заинтересует
- Сигнализации для дачи
- Охранные системы
- Пожарные сигнализации
- Установка сигнализации
- Ремонт сигнализаций
- ЧОП
- Сигнализации на авто
- Сигнализации для дома
- Монтаж
- Охранная сигнализация
- Монтаж охранно-пожарных систем
- Системы охранной сигнализации
-
Подробнее о виде деятельности
-
Дополнительно компания занимается
Способы оплаты
-
На месте
- Наличный расчет
-
Дистанционно
- По счету (для юр. лиц)
Категории компании
- Системы безопасности, средства охраны в Кургане
- Услуги монтажа пожароохранных систем в Кургане
-
Похожие места рядом
184м
Макар
Курган, Красина, 49, 109 офис; 1 этаж
298м
Меркурий
Курган, Красина, 53, 72 офис; 4 этаж
462м
Виссон
Курган, Советская, 24
494м
Кентавр
Курган, Красина, 68а, 3 офис; 2 этаж
647м
Транзит
Курган, Куйбышева, 35, 401/5 офис; 4 этаж
663м
СОБР
Курган, Володарского, 57, 404 офис; 4 этаж
Отзывы о Питон
Если вы имеете реальный опыт общения с данной компанией, то просим вас оставить небольшой отзыв: это поможет другим сориентироваться среди
43 компании в этой сфере.
Огромное спасибо!
Регистрация не требуется
Добавить отзыв
Курган Услуги охранных организаций в Кургане Питон, Частная охранная организация
Как организовать код Python 🐍📦
графический интерфейс совершено 3 месяца назад · 🐍 Питон
За каждую минуту, потраченную на организацию, начисляется час.
Бенджамин Франклин
Python отличается от таких языков, как C# или Java, где они заставляют вас иметь классы, названные в честь файла, в котором они живут. повышает вероятность принятия неверных решений.
- Вы хотите сохранить все классы проекта в одном
файл main.py
? Да, это работает. - Вам нужно прочитать переменную среды ОС? Просто прочитайте это прямо там.
- Вам нужно изменить поведение функции? Почему не декоратор!?
Многие решения, которые легко реализовать, могут иметь неприятные последствия, создавая код, который чрезвычайно сложно поддерживать.
Это не обязательно плохо , если вы знаете, что делаете.
В этой главе я собираюсь представить вам рекомендации, которые сработали для меня в прошлом, когда я работал в разных компаниях и с разными людьми.
🌳 Структурируйте свой проект Python
Сначала сосредоточимся на структуре каталогов, именовании файлов и организации модулей.
Я рекомендую вам хранить все ваши файлы модулей внутри каталога src
, а все тесты жить рядом с ним:
Проект верхнего уровня
<проект> ├── источник │ ├── <модуль>/* │ │ ├── __init__.py │ │ └── many_files.py │ │ │ └── тесты/* │ └── many_tests.py │ ├── .gitignore ├── pyproject.toml └── README.md
Где <модуль>
— ваш основной модуль. Если вы сомневаетесь, подумайте, какие люди будут pip устанавливать
и как вы хотели бы импортировать модуль
.
Часто имеет то же имя, что и главный проект. Хотя это не правило.
🎯 Обоснование каталога
src
Я видел много проектов, которые работали по-разному.
Некоторые варианты включают отсутствие src
dir со всеми модулями проекта вокруг дерева.
Это очень раздражает из-за отсутствия порядка, создавая такие вещи, как (пример):
non_recommended_project ├──/* │ ├── __init__.py │ └── many_files.py │ ├── .gitignore │ ├── тесты/* │ └── many_tests.py │ ├── pyproject.toml │ ├── /* │ ├── __init__.py │ └── many_files.py │ └── README.md
Скучно иметь вещи так далеко друг от друга из-за алфавитной сортировки IDE.
Основная причина src
dir предназначен для хранения активного кода проекта в одном каталоге, в то время как настройки, настройка CI/CD и метаданные проекта могут находиться за его пределами.
Единственным недостатком этого является то, что вы не можете импортировать module_a
в свой код Python из коробки. Нам нужно настроить проект для установки в этот репозиторий. Вскоре в этой главе мы обсудим, как решить эту проблему.
🏷️ Как назвать файлы
Правило 1: Нет файлов
Во-первых, в Python нет таких вещей, как «файлы», и я заметил, что это основной источник путаницы для начинающих.
Если вы находитесь внутри каталога, который содержит __init__.py
, это каталог, состоящий из модулей, а не файлов.
См. каждый модуль как пространство имен.
Я имею в виду пространство имен, потому что нельзя точно сказать, много ли в них функций, классов или просто констант. В нем могут быть практически все из них или только некоторые из них.
Правило 2: Объединяйте вещи по мере необходимости
Несколько классов в одном модуле — это нормально , и вы должны это делать. (очевидно, когда классы связаны с модулем).
Часто люди думают, что это плохая практика из-за некоторого опыта работы с другими языками, которые требуют обратного (например, Java и C#).
Правило 3: По умолчанию давайте имена во множественном числе
Как правило, называйте свои модули во множественном числе и называйте их в соответствии с бизнес-контекстом.
Однако из этого правила есть исключения! Модули могут называться core
, main.py
и так далее, чтобы представлять одно целое. Используйте свое суждение, если сомневаетесь, придерживайтесь правила множественного числа.
🔎 Реальный пример именования модулей
В качестве примера я поделюсь проектом Google Maps Crawler, который я создал.
Этот проект отвечает за сканирование данных из Google Maps с использованием Selenium и их вывод (подробнее здесь, если интересно).
Это текущее дерево проекта с исключениями из правила №3:
gmaps_crawler ├── источник │ └── gmaps_crawler │ ├── __init__.py │ ├── config.py 👈 (Единственное число) │ ├── drivers.py │ ├── entity.py │ ├── исключения.py │ ├── фасады. py │ ├── main.py 👈 (Единственное число) │ └── storages.py │ ├── .gitignore ├── pyproject.toml └── README.md
Вполне естественно импортировать такие классы и функции, как:
из gmaps_crawler.storages import get_storage из gmaps_crawler.entities импортировать место из gmaps_crawler.exceptions импортировать CantEmitPlace
Я понимаю, что у меня может быть один или несколько классов исключений внутри исключений
и так далее.
Прелесть нескольких модулей в том, что:
- Они не слишком маленькие (например, по одному на класс)
- При необходимости вы можете в любой момент разбить модуль на более мелкие
- Они дают вам четкое представление о том, что может находиться внутри
🔖 Именование классов, функций и переменных
Некоторые люди утверждают, что давать имена вещам сложно. Это становится менее сложным, когда вы определяете некоторые руководящие принципы.
👊 Функции и методы должны быть глаголами
Функции и методы представляют действие или действия.
Что-то «не». Что-то происходит».
Действия четко обозначаются глаголами.
Несколько хороших примеров из РЕАЛЬНЫХ проектов, над которыми я работал раньше:
определение get_orders(): ... определение подтверждения_события(): ... защита get_delivery_information(): ... опубликовать (): ...
Несколько плохих примеров:
def email_send(): ... определение api_call(): ... определение конкретного_материала(): ...
Они немного неясны, возвращают ли они объект, чтобы позволить мне выполнить вызов API, или, например, он действительно отправляет электронное письмо.
Я могу представить такой сценарий:
email_send.title = "title" email_send.dispatch()Пример вводящего в заблуждение имени функции
Исключения из этого правила немногочисленны, но они существуют.
- Создание функции
main()
, которая будет вызываться в основной точке входа вашего приложения, является веской причиной, чтобы пропустить это правило. - Использование
@property
для обработки метода класса как атрибута также допустимо.
🐶 Переменные и константы должны быть существительными
Всегда должны быть существительными, а не глаголами (что разъясняет разницу между функциями).
Хорошие примеры:
плоскость = плоскость() идентификатор_клиента = 5 KEY_COMPARISON = "абв"
Плохие примеры:
fly = Plane() get_customer_id = 5 COMPARE_KEY = "абв"
Если ваша переменная/константа представляет собой список или набор, укажите множественное число!
planes: list[Plane] = [Plane()] # 👈 Даже если он содержит только один элемент customer_ids: set[int] = {5, 12, 22} KEY_MAP: dict[str, str] = {"123": "abc"} # 👈 Словари сохраняются в единственном числе
🏛️ Классы должны быть понятными, но суффиксы в порядке
Предпочитайте классы с понятными именами. Можно использовать такие суффиксы, как Сервис
, Стратегия
, Промежуточное ПО
, но только тогда, когда это крайне необходимо, чтобы прояснить его назначение.
Всегда называйте его в единственном числе вместо множественного числа. Множественное число напоминает нам о коллекциях (например, если я читаю заказов,
я предполагаю, что это список или итерация), поэтому напомните себе, что после создания экземпляра класса он становится единым объектом.
Классы, представляющие объекты
Классы, которые представляют вещи из бизнес-контекста, должны называться как есть (существительные!). Как Заказ
, Продажа
, Магазин
, Ресторан
и так далее.
Пример использования суффиксов
Предположим, вы хотите создать класс, отвечающий за отправку электронных писем. Если вы назовете его просто как « Email
», его назначение неясно.
Кто-то может подумать, что это может представлять сущность, например.
email = Email() # предполагаемый пример использования email.title = "Заголовок" электронная почта. тело = create_body() email.send_to = "guilatrova.dev" send_email (электронная почта)
Вы должны назвать его « EmailSender
» или « EmailService
«.
🐪 Условные обозначения регистров
По умолчанию используются следующие соглашения об именах:
Тип | Общедоступный | Внутренний |
---|---|---|
Пакеты (каталоги) | ниже_с_под | — |
Модули (файлы) | нижний_с_под.py | — |
Классы | CapWords | — |
Функции и методы | ниже_с_под() | _lower_with_under() |
Константы | ALL_CAPS_UNDER | _ALL_CAPS_UNDER |
⚠️ Заявление об отказе от «частных» методов.
Некоторые люди обнаружили, что если у вас есть __method(self)
(любой метод, начинающийся с двух символов подчеркивания) Python не позволит внешним классам/методам вызывать его нормально, что заставляет их думать, что это нормально.
Если вы пришли из среды C#, как и я, может показаться странным, что вы не можете защитить метод.
Но у Гвидо (создателя Python) есть на то веская причина:
«Мы все здесь взрослые по обоюдному согласию»
Это означает, что если вы знаете, что вам не следует вызывать метод, то вы не должны если вы не знаете, что делаете.
В конце концов, если вы действительно решили вызвать этот метод, вы собираетесь сделать что-то грязное, чтобы это произошло (известное как «Отражение» в C#).
Отметьте свой частный метод/функцию одним начальным символом подчеркивания, чтобы указать, что он предназначен только для частного использования и жить с ним.
↪️ Когда создавать функцию или класс в Python?
Это общий вопрос, который я получил несколько раз.
Если вы будете следовать приведенным выше рекомендациям, у вас будут четкие модули, а четкие модули — эффективный способ организации функций:
из хранилища импорта gmaps_crawler storages. get_storage() # 👈 Подобно классу, за исключением того, что он не создан и имеет имя во множественном числе storages.save_to_storage() # 👈 Потенциальная функция внутри модуля
Иногда вы можете идентифицировать подмножества функций внутри модуля. Когда это происходит, класс имеет больше смысла:
Пример группировки различных подмножеств функций
Рассмотрим тот же модуль хранилищ
с 4 функциями:
def format_for_debug(some_data): ... защита save_debug (некоторые_данные): """Отпечатки на экране""" форматированные_данные = формат_для_отладки (некоторые_данные) печать (форматированные_данные) защита create_s3 (ведро): """Создать корзину s3, если она не существует""" ... защита save_s3 (некоторые_данные): s3 = create_s3 ("имя_сегмента") ...
S3 — это облачное хранилище для хранения любых данных, предоставляемых Amazon (AWS). Это как Google Drive для программного обеспечения.
Можно сказать, что:
- Разработчик может сохранять данные в режиме DEBUG (который просто выводит на экран) или на S3 (который хранит данные в облаке).
-
save_debug
использует функциюformat_for_debug
-
save_s3
использует функциюcreate_s3
Я вижу две группы функций в разных модулях, и поэтому я вижу две группы функций в разных модулях, и нет причин хранить их в разных модулях, и нет причин нравится определять их как классы:
класс DebugStorage: def format_for_debug (я, некоторые_данные): ... def save_debug (я, некоторые_данные): """Отпечатки на экране""" formatted_data = self.format_for_debug(some_data) печать (форматированные_данные) класс S3Storage: def create_s3 (я, ведро): """Создать корзину s3, если она не существует""" ... защита save_s3 (я, некоторые_данные): s3 = self.create_s3 ("bucket_name") ...
Вот эмпирическое правило:
- Всегда начинайте с функций
- Переходите к классам, как только почувствуете, что можете группировать различные подмножества функций
🚪 Создание модулей и точек входа
Каждое приложение имеет точку входа.
Это означает, что существует единственный модуль (также известный как файл), который запускает ваше приложение. Это может быть как отдельный скрипт, так и большой модуль.
Всякий раз, когда вы создаете точку входа, не забудьте добавить условие, гарантирующее, что она выполняется, а не импортируется :
по умолчанию execute_main(): ... if __name__ == "__main__": # 👈 Добавьте это условие execute_main()
Делая это, вы гарантируете, что любой импорт не вызовет случайного срабатывания вашего кода. Если это не выполняется явно.
Определение main для модулей
Вы могли заметить некоторые пакеты Python, которые можно вызвать, передав -m
, например:
python -m pytest python -m трицератопс питон -м фауст питон -м хлопья8 питон -м черный
Такие пакеты обрабатываются почти как обычные команды, поскольку вы также можете запускать их как:
pytest трицератопс Фауст хлопья8 черный
Чтобы это произошло, вам нужно указать один файл __main__. py
внутри основного модуля:
├── источник │ ├── пример_модуля 👈 Основной модуль │ │ ├── __init__.py │ │ ├── __main__.py 👈 Добавить сюда │ │ └── many_files.py │ │ │ └── тесты/* │ └── many_tests.py │ ├── .gitignore ├── pyproject.toml └── README.md
Не забывайте, что вам все равно нужно включить проверку __name__ == "__main__"
в файл __main__.py
.
Когда вы устанавливаете свой модуль, вы можете запустить свой проект как python -m example_module
.
📖 Привет!
Это первоначальный набросок книги, которую я пишу!
Если вам интересно, подпишитесь на на информационный бюллетень и подпишитесь на меня в Твиттере чтобы получать уведомления, когда книга выйдет!
Первая глава вышла со специальной скидкой!
Python Like a PRO 🐍📚 Книга
⚠️📚 Эта книга все еще находится в разработке (поэтому сейчас она такая дешевая, цена вырастет после публикации всех глав). Вам нужно знать, что, черт возьми, вы делаете делать 🔥🐍Python — один из самых гибких языков, с которыми я когда-либо общался. Все, что слишком гибко, увеличивает шансы на…
Gumroad
есть какие-либо.
🚀 Не пропустите следующие посты! 📥
Узнайте, как организовать код Python с помощью модулей и пакетов за 5 минут | by Erdem Isbilen
Photo by Zach Kadolph on UnsplashКогда ваш код Python увеличивается в размерах, скорее всего, со временем он становится неорганизованным. Хранение вашего кода в одном и том же файле по мере его роста затрудняет поддержку вашего кода. На этом этапе модули Python и пакеты помогут вам организовать и сгруппировать содержимое с помощью файлов и папок.
- Модули — это файлы с расширением «.py» , содержащие код Python. Они помогают организовать связанные функции, классы или любой блок кода в одном файле.
- Рекомендуется разбивать большие блоки кода Python на модуля , содержащих до 300–400 строк кода.
- Пакеты группируют похожие модули в отдельный каталог. Это папки, содержащие связанные модули и файл __init__.py 9.0023, который используется для дополнительной инициализации на уровне пакета.
- В зависимости от вашего приложения Python вы можете сгруппировать свои модули в подпакеты, такие как doc, core, utils, data, examples, test.
Давайте напишем пример кода Python3 для лучшего понимания модулей и пакетов:
""" cvs_get_module.pyPhoto by Daniel on Unsplash
Этот модуль отображает сводку табличных данных, содержащихся в файле CSV ("cvs_get_module загружен") DEF DISPANE_FILE_LOCATION ( PATH, FILE_NAME ) :
ПЕЧАТА ("Расположение файла: {}". Формат (PATH+FILENAME)) Class CSVGETINFO:
DEF ____5050305030503050505050505050505050505050505050505050505050505cн. путь , имя_файла ):
self.path = путь
self.file_name = имя_файлаdef display_summary( self ):
data = pd.read_csv(self.path) + self.path 90 (self.file_name)
print(data.info())
Чтобы использовать модуль во внешнем блоке кода Python, нам нужно импортировать этот конкретный модуль в нашу структуру кода. Для этого используется оператор import с синтаксисом « import < module_name > ». Имя модуля здесь относится к имени файла Python без расширения «.py» . Как только мы импортируем модуль, мы используем точечную нотацию «.», для доступа к элементам внутри модуля.
# ModulesExample.py
# Importing 'csv_get_module' and accessing its elements import csv_get_module data_by_genres = csv_get_module.CSVGetInfo ("/Users/erdemisbilen/
Lessons/", "data_by_genres. csv") csv_get_module.display_file_location (данные_по_жанрам. путь , данные_по_жанрам. имя_файла )данные_по_жанрам. display_summary() Вывод:
cvs_get_module загружен
Расположение файла: /Users/erdemisbilen/Lessons/data_by_genres.csv
data_by_genres.csv
RangeIndex: 2617 записей, от 0 до 2616
Столбцы данных (всего 14 столбцов):
Мы можем переименовать модуль при импорте с помощью ‘import < имя_модуля > as < альтернативное_имя >’ синтаксис. Это может быть полезно для сокращения длинных имен модулей.
# ModulesExample.pyФото Алекса Блока на Unsplash
# Импорт csv_get_module и доступ к его элементам import csv_get_module as cg data_by_genres = cg.CSVGetInfo ("/Users/erdemisbilen/Lessons/", "data_by_genres. csv") cg.display_file_location (data_by_genres_by_genres.data_path(), data_by_genres. Вывод:
cvs_get_module загружен
Местоположение файла: /Users/erdemisbilen/Lessons/data_by_genres.csv
data_by_genres.csv
RangeIndex: 26171 записей, от 0 до 26005 столбцы (всего 14 столбцов):
Мы можем импортировать определенные имена модуля, кроме загрузки всех элементов, содержащихся в модуле. Кроме того, мы можем импортировать несколько элементов, разделяя имена запятыми.
Обратите внимание, что нам не нужно использовать здесь запись через точку, так как мы напрямую импортируем имя с синтаксисом ‘from < имя_модуля > импорт < имя_элемента >’ .
из csv_get_module импорт display_file_location as dfl dfl ("/User/Python/","ModulesExample. py") Вывод:
Расположение файла: /UserModulesExample.py
Мы также можем напрямую импортировать все имена модулей, используя звездочку (*), хотя это не считается хорошей практикой. Это может привести к конфликту имен, если вы импортируете несколько модулей, содержащих элементы с одинаковыми именами.
from csv_get_module import *
Если мы хотим скрыть некоторые элементы модуля, мы можем назвать элемент, начинающийся с подчеркивания «_» . Такой элемент нельзя импортировать во внешние файлы, так как это соглашение об именах делает элемент закрытым для самого модуля.
Файл, содержащий коды Python, можно запускать как отдельный скрипт или загружать в другую структуру кода как модуль.
Иногда необходимо разделить код внутри файла Python с учетом такого использования. Python имеет встроенный атрибут __name__ , который дает нам имя модуля , когда файл загружается как модуль. Когда файл запускается как автономный скрипт, на этот раз он возвращает __main__ строка.
""" cvs_get_module.py
Этот модуль отображает сводку табличных данных, содержащихся в файле CSV
""" ) :
Print ("Расположение файла: {}". Format (Path+Eallename)) Класс CSVGETINFO:
DEF __INIT __ ( Self , PATH , файл.0005 self.path = path
self.file_name = file_namedef display_summary( self ):
data = pd.read_csv(self.path + self.file_name)
print(self.file_name)
print( data.info())if __name__ == '__main__' : data_by_genres = CSVGetInfo ("/Users/erdemisbilen/Lessons/",
"data_by_genres.csv") display_file_path 9_5_genres.data data_by_genres.file_name) data_by_genres.display_summary()
Коды внутри инструкции if запускаются только тогда, когда скрипт запускается как автономный скрипт.
Пакеты группируют похожие модули в отдельный каталог. Это папки, содержащие связанные модули и файл __init__.py , который используется для дополнительной инициализации на уровне пакета.
__init__.py выполняется один раз при ссылке на модуль внутри пакета. Этот файл можно оставить пустым или опционально реализовать код инициализации на уровне пакета.
В зависимости от вашего приложения Python вы можете сгруппировать свои модули в подпакеты, такие как doc, core, utils, data, examples, test. Это делает вашу общую структуру хорошо организованной и поддерживаемой, поскольку аналогичные модули хранятся в отдельных папках.
Фото Линн Кинцигер на UnsplashМы можем импортировать модули внутри пакетов, используя имя пакета (имя папки) и оператор точки «.».
из utils.csv_get_module импорт display_file_location as dfl dfl ("/User/Python/","ModulesExample. py") Вывод:
Расположение файла: /UserModulesExample.py
- В Python организация больших блоков кода управляется модулями Пакеты и .
- Это упрощает структуру кода, увеличивает возможность повторного использования кода и упрощает обслуживание и тестирование.
В этом посте я объяснил основы модулей и пакетов в Python.
Код в этом посте доступен в моем репозитории GitHub.
Надеюсь, этот пост был вам полезен.
Спасибо за внимание!
Хороший способ структурировать проект Python | Наджма Бадер
Простые советы по Python Я хотел бы знать их как начинающий специалист по работе с данными Фото Фионы СмоллвудНезависимо от того, работаете ли вы над проектом самостоятельно или сотрудничаете с поможет вам поддерживать порядок в вашем пространстве .
- Совет №1: Создайте виртуальную среду
- Совет №2: Создайте отдельный каталог для тестов
- Совет №3: Создайте разные каталоги содержимого
Если вы хотите пойти дальше, вам также следует:
- Совет № 4. Документируйте свой код
- Совет № 5. Используйте GitHub для контроля версий
Некоторые разделы связаны с PyCharm. Вы можете пропустить его, если используете другую IDE.
Для того, чтобы пространство для вашего проекта работало, рекомендуется создайте виртуальную среду и изолируйте свои зависимости.
Вы можете использовать модуль Python venv
и указать версию Python и имя среды. В приведенном ниже примере я использую Python3 и вызываю среду venv. После того, как вы создали каталог, вам нужно запустить внутри него скрипт , активировать
.
Сводка команд:
-
python3 -m venv venv
→ Создает A Virtual Environment -
Source Wenv/Bin/Activate
→ Активирует Эвпача -
Деактиват
→ DeActivates . Environment
venv
, появившийся в каталоге вашего проекта слева. В нем автоматически устанавливается ряд вещей. Скорее всего, вас волнует только активация 9Скрипт 0014 — как мы видели выше. Изображение автора Важно отметить, что в PyCharm вы должны сделать дополнительный шаг, чтобы ваши программы могли работать в вашей виртуальной среде.
Перейти в правый нижний угол. Вы должны увидеть, какой интерпретатор использует PyCharm.
Изображение автора Нажмите «Добавить интерпретатор» и выберите вариант «Существующая среда».
Затем перейдите в папку, в которой вы создали среду, и выберите Python из списка 9.0013 бин
каталог. Изображение автора Если все работает правильно, вы должны увидеть в правом нижнем углу версию Python, существующую в вашей виртуальной среде. Хороший! 🎊
Изображение автораВкратце, виртуальные среды позволяют:
- Поддерживать изолированные зависимости. Это позволяет избежать ситуаций, когда у вас есть проекты, использующие разные версии пакетов, и вы глобально удаляете/переустанавливаете то, что вам нужно, каждый раз, когда вам нужно запустить проект.
- Поделитесь своими зависимостями с другими людьми.
После того, как вы установили все пакеты, необходимые для вашего проекта, вы можете запустить:
замораживание пакетов > требования.txt
замораживание пакетов
«замораживает» все используемые пакеты/версии. Затем вы передаете (т. Е. Сохраняете) вывод pip freeze
через текстовый файл.
Другие люди, использующие вашу программу, будут запускать:
pip install -r requirements.txt
и иметь возможность установить все пакеты и правильные версии за один раз. Удивительно, верно? 🚀
Изображение автораВы слышали, что создавать тесты для своего кода — хорошая идея. Итак, вы пишете код на Python и пытаетесь протестировать его с помощью Pytest.
Пример: Предположим, вы создали файл с именем Greetings.py
и еще один для написания тестов с именем test_greetings. py
.
В этом примере я буду использовать Pytest в качестве пакета для тестирования. Pytest имеет много соглашений об именах. Начиная имя файла с test_
— один из них. Если вы будете следовать ему, Pytest автоматически найдет в текущем каталоге и в каталогах под ним те файлы, которые начинаются с test_
, и запустит их.
Чтобы создать новые файлы, вы можете использовать команду touch
в своем терминале:
В верхней правой части PyCharm вы должны увидеть что-то вроде:
Изображение автора Открыть Greetings.py
и напишите простую функцию:
В своем терминале вы можете запустить pip install pytest
для установки модуля pytest
, а затем просто pytest
. Поскольку вы еще не определили ни одного теста, pytest
запустится, но соберет 0 элементов.
Откройте test_greetings. py
и напишите тестовую функцию:
Если вы заметили, имя функции также должно начинаться с test_
, например. test_say_hello
. Это еще одно соглашение об именах Pytest.
Как отлаживать ModuleNotFound Ошибка
Еще одна хорошая идея — собрать все тесты в одном каталоге.
Однако, если вы просто сделаете это, когда вы сейчас запустите pytest
, вы увидите, что ни один из ваших тестов не работает. Если вы присмотритесь, вы, вероятно, получите ModuleNotFoundError
.
Посмотрим, что случилось и как это исправить.
Изображение автора Pytest пытается импортировать модуль приветствия
, но это не удается.
Самый простой способ исправить это — представить, что каталог test
является пакетом (то есть набором модулей). В каталоге создайте файл с именем __init__.py
Это совершенно пустой файл:
Изображение автораОднако сам факт присутствия заставляет ваш тест снова работать.
Изображение автораВуаля! 🍷
Теперь, когда у вас появилась идея создать файл __init__.py
, вы можете создать столько каталогов, сколько захотите.
Например:
В основном:
__init__.py
используется для пометки каталогов как каталогов пакетов Python
. Следовательно, если вы попытаетесь импортировать модуль куда-то еще, это не удастся.
Документирование вашего кода очень важно как для «будущего», так и для других людей, читающих ваш проект. Некоторые программисты даже говорят:
Если ваш код сложно документировать, рассмотрите возможность изменения дизайна.
Есть 3 важные вещи, которые вы должны иметь в виду:
- Добавьте строку документации с описанием в начале каждого файла
2. Добавьте строку документации к каждой функции и классу
Изображение by author3. Используйте подсказки типов всякий раз, когда вы определяете функцию или класс
Изображение автора Подсказки типов (1) делают функции и классы более читабельными, (2) позволяют обойти указание типа параметров в документации, и (3) вы можете использовать их для автоматической проверки вашего кода с помощью mypy
. 🎖
Существует множество руководств по стилю для написания хорошей документации. Мне лично нравится Google Style Python Docstring .
Если вы работаете с кем-то еще, Git + GitHub
необходимы для проверки кода и предотвращения конфликтов слияния.
Если вы работаете в одиночку, они по-прежнему полезны для сохранения вашей работы и возможности отменить изменения и «вернуться в прошлое».
🐢 Если вы новичок в этих концепциях, вы можете найти дополнительную информацию здесь:
- Введение в Git и GitHub для разработчиков Python (бесплатно)
- Новый журнал: О, черт, мерзавец! (платно)
😱 Если вы начинаете паниковать, когда начинаете использовать систему контроля версий:
- О, черт, черт!?!
💪 Если вы хотите узнать больше:
- Добро пожаловать в изучение Git Branching
Первый подход с Git ужасен, но я обещаю, что он окупится. Мы все там были 🙇♀️
Надеюсь, это было полезно! ⚡️
Ссылки
- Новый курс: Тестирование программ Python с помощью pytest от Реувена Лернера
- https://flax.readthedocs.io/en/latest/philosophy.html
- http://web.archive. org/web/20111010053227/
- http://jaynes.colorado.edu/PythonGuidelines.html#module_formatting
- https://realpython.com/lessons/type-checking-mypy/
- Для чего используется __init__.py ?
A Эталон – настоящий Python
Смотреть сейчас Это руководство содержит связанный с ним видеокурс, созданный командой Real Python. Посмотрите его вместе с письменным учебным пособием, чтобы углубить свое понимание: Структурирование приложения Python
Python, хотя и самоуверен в отношении синтаксиса и стиля, удивительно гибок, когда дело доходит до структурирования ваших приложений.
С одной стороны, эта гибкость велика: она позволяет различным вариантам использования использовать структуры, необходимые для этих вариантов использования. С другой стороны, это может сильно запутать нового разработчика.
Интернет тоже не очень помогает — мнений столько же, сколько блогов по Python. В этой статье я хочу дать вам надежное справочное руководство по компоновке приложений Python, к которому вы можете обратиться в подавляющем большинстве случаев использования .
Вы увидите примеры распространенных структур приложений Python, включая приложения командной строки (приложения CLI), одноразовые сценарии, устанавливаемые пакеты и макеты веб-приложений с популярными платформами, такими как Flask и Django.
Примечание: Это справочное руководство предполагает наличие практических знаний о модулях и пакетах Python. Ознакомьтесь с нашим введением в модули и пакеты Python для освежения знаний, если вы чувствуете себя немного заржавевшим.
Макеты приложений командной строки
Многие из нас работают в основном с приложениями Python, которые запускаются через интерфейсы командной строки (CLI). Здесь вы часто начинаете с чистого листа, и гибкость макетов приложений Python может стать настоящей головной болью.
Начало работы с пустой папкой проекта может быть пугающим и не приведет к нехватке блока кодировщика. В этом разделе я хочу поделиться некоторыми проверенными макетами, которые я лично использую в качестве отправной точки для всех своих приложений Python CLI.
Мы начнем с очень простого макета для очень простого варианта использования: простого скрипта, который работает сам по себе. Затем вы увидите, как создавать макет по мере продвижения вариантов использования.
Удалить рекламу
Одноразовый сценарий
Вы просто делаете скрипт .py
, и он хорош, верно? Не нужно устанавливать — просто запустите скрипт в его каталоге!
Хорошо, если вы просто делаете скрипт для собственного использования или не имеет никаких внешних зависимостей, но что, если вам нужно его распространять? Особенно для менее технически подкованного пользователя?
Следующий макет подойдет для всех этих случаев и может быть легко изменен, чтобы отразить любую установку или другие инструменты, которые вы используете в своем рабочем процессе. Этот макет охватывает вас, создаете ли вы чистый скрипт Python (то есть скрипт без зависимостей) или используете такой инструмент, как pip или Pipenv.
Пока вы читаете это справочное руководство, имейте в виду, что точное расположение файлов в макете имеет меньшее значение, чем причина, по которой они размещены там, где они находятся. Все эти файлы должны находиться в каталоге проекта, названном в честь вашего проекта. В этом примере мы будем использовать (что еще?) helloworld
в качестве имени проекта и корневого каталога.
Вот структура проекта Python, которую я обычно использую для CLI-приложения:
привет мир/ │ ├── .gitignore ├── helloworld.py ├── ЛИЦЕНЗИЯ ├── README.md ├── требования.txt ├── setup.py └──tests.py
Это довольно просто: все находится в одном каталоге. Показанные здесь файлы не обязательно являются исчерпывающими, но я рекомендую свести количество файлов к минимуму, если вы планируете использовать такой базовый макет. Некоторые из этих файлов будут для вас новыми, поэтому давайте кратко рассмотрим, что делает каждый из них.
.gitignore
: это файл, который сообщает Git, какие типы файлов игнорировать, например, беспорядок IDE или локальные файлы конфигурации. В нашем руководстве по Git есть все подробности, и вы можете найти пример 9.0013 .gitignore файлов для проектов Python здесь.helloworld.py
: Это скрипт, который вы распространяете. Что касается именования основного файла сценария, я рекомендую вам использовать имя вашего проекта (которое совпадает с именем каталога верхнего уровня).ЛИЦЕНЗИЯ
: Этот текстовый файл описывает лицензию, которую вы используете для проекта. Всегда полезно иметь его, если вы распространяете код. Имя файла пишется заглавными буквами по соглашению.Примечание: Нужна помощь в выборе лицензии для вашего проекта? Проверьте ChooseALicense.
README.md
: Это файл Markdown (или reStructuredText), документирующий назначение и использование вашего приложения. Создание хорошегоREADME
— это искусство, но здесь вы можете найти путь к мастерству.requirements.txt
: Этот файл определяет внешние зависимости Python и их версии для вашего приложения.setup.py
: этот файл также можно использовать для определения зависимостей, но он отлично подходит для другой работы, которую необходимо выполнить во время установки. Вы можете узнать больше оsetup.py
иrequirements.txt
в нашем руководстве по Pipenv.tests.py
: Этот скрипт содержит ваши тесты, если они у вас есть. Вы должны иметь некоторые.
Но теперь, когда ваше приложение растет и вы разбили его на несколько частей в одном пакете, должны ли вы хранить все части в каталоге верхнего уровня? Теперь, когда ваше приложение усложнилось, пришло время организовать его более четко.
Устанавливаемый отдельный пакет
Давайте представим, что helloworld.py
по-прежнему является основным скриптом для выполнения, но вы переместили все вспомогательные методы в новый файл с именем helpers.py
.
Мы собираемся упаковать файлы helloworld
Python вместе, но сохранить все разные файлы, такие как README
, .gitignore
и т. д., в верхнем каталоге.
Взглянем на обновленную структуру:
привет мир/ │ ├── привет мир/ │ ├── __init__.py │ ├── helloworld.py │ └── helpers.py │ ├── тесты/ │ ├── helloworld_tests.py │ └── helpers_tests.py │ ├── .gitignore ├── ЛИЦЕНЗИЯ ├── README.md ├── требования.txt └── setup.py
Единственное отличие состоит в том, что весь код вашего приложения теперь хранится в подкаталоге helloworld
— этот каталог назван в честь вашего пакета — и что мы добавили файл с именем __init__.py
. Давайте представим эти новые файлы:
helloworld/__init__. py
: Этот файл имеет много функций, но для наших целей он сообщает интерпретатору Python, что этот каталог является каталогом пакета. Вы можете настроить этот файл__init__.py
таким образом, чтобы вы могли импортировать классы и методы из пакета в целом, вместо того, чтобы знать внутреннюю структуру модуля и импортировать изhelloworld.helloworld
илиhelloworld.helpers
.Примечание: Более подробно о внутренних пакетах и
__init__.py
читайте в нашем обзоре модулей и пакетов Python.helloworld/helpers.py
: Как упоминалось выше, мы переместили большую часть бизнес-логикиhelloworld.py
в этот файл. Благодаря__init__.py
внешние модули смогут получить доступ к этим помощникам, просто импортировав их из пакетаhelloworld
.тестов/
: Мы переместили наши тесты в отдельный каталог, и вы будете наблюдать эту закономерность по мере усложнения структур наших программ. Мы также разделили наши тесты на отдельные модули, отражая структуру нашего пакета.
Этот макет представляет собой урезанную версию структуры приложения Samplemod Кеннета Рейца. Это еще одна отличная отправная точка для ваших приложений CLI, особенно для более масштабных проектов.
Приложение с внутренними пакетами
В более крупных приложениях у вас может быть один или несколько внутренних пакетов, которые либо связаны вместе с основным сценарием запуска, либо предоставляют определенные функции для более крупной библиотеки, которую вы упаковываете. Мы расширим соглашения, изложенные выше, чтобы учесть это:
привет мир/ │ ├── бин/ │ ├── документы/ │ ├── hello.md │ └── world.md │ ├── привет мир/ │ ├── __init__.py │ ├── runner.py │ ├── привет/ │ │ ├── __init__.py │ │ ├── hello.py │ │ └── helpers.py │ │ │ └── мир/ │ ├── __init__.py │ ├── helpers.py │ └── world.py │ ├── данные/ │ ├── input.csv │ └── output.xlsx │ ├── тесты/ │ ├── привет │ │ ├── helpers_tests. py │ │ └── hello_tests.py │ │ │ └── мир/ │ ├── helpers_tests.py │ └── world_tests.py │ ├── .gitignore ├── ЛИЦЕНЗИЯ └── README.md
Здесь нужно еще немного разобраться, но если вы помните, что это следует из предыдущего макета, вам будет легче следовать за ним. Я рассмотрю дополнения и модификации по порядку, их использование и причины, по которым они могут вам понадобиться.
bin/
: В этом каталоге хранятся все исполняемые файлы. Я адаптировал это из классического поста Жана-Поля Кальдерона о структуре, и его рекомендации по использованию каталогаbin/
по-прежнему важны. Самый важный момент, который следует помнить, это то, что ваш исполняемый файл не должен содержать много кода, только импорт и вызов основной функции в вашем скрипте запуска. Если вы используете чистый Python или у вас нет исполняемых файлов, вы можете пропустить этот каталог./docs
: С более продвинутым приложением вы захотите вести хорошую документацию по всем его частям. Мне нравится размещать здесь любую документацию для внутренних модулей, поэтому вы видите отдельные документы для пакетовhello
иworld
. Если вы используете строки документации в своих внутренних модулях (и вы должны!), ваша документация по всему модулю должна, по крайней мере, давать целостное представление о назначении и функциях модуля.helloworld/
: Это похоже наhelloworld/
в предыдущей структуре, но теперь есть подкаталоги. По мере усложнения вы захотите использовать тактику «разделяй и властвуй» и разделять части логики вашего приложения на более управляемые фрагменты. Помните, что имя каталога относится к общему имени пакета, поэтому имена подкаталогов (hello/
иworld/
) должны отражать имена пакетов.data/
: Наличие этого каталога полезно для тестирования. Это центральное место для любых файлов, которые ваше приложение будет принимать или создавать. В зависимости от того, как вы развертываете свое приложение, вы можете сохранять входные и выходные данные «производственного уровня» в этот каталог или использовать его только для внутреннего тестирования.тестов/
: Здесь вы можете поместить все свои тесты — модульные тесты, тесты выполнения, интеграционные тесты и так далее. Не стесняйтесь структурировать этот каталог наиболее удобным способом для ваших стратегий тестирования, стратегий импорта и многого другого. Чтобы узнать о тестировании приложений командной строки с помощью Python, ознакомьтесь с моей статьей 4 «Методы тестирования приложений командной строки Python (CLI)».
Файлы верхнего уровня остаются в основном такими же, как и в предыдущем макете. Эти три макета должны охватывать большинство случаев использования приложений командной строки и даже приложений с графическим интерфейсом с той оговоркой, что вам, возможно, придется повозиться с некоторыми вещами в зависимости от используемой среды графического интерфейса.
Примечание: Имейте в виду, что это всего лишь макеты. Если каталог или файл не имеет смысла для вашего конкретного варианта использования (например, тестов/
, если вы не распространяете тесты вместе со своим кодом), не стесняйтесь их пропускать. Но постарайтесь не пропустить документы/
. Всегда полезно документировать свою работу.
Удалить рекламу
Макеты веб-приложений
Еще одним важным вариантом использования Python являются веб-приложения. Django и Flask, пожалуй, самые популярные веб-фреймворки для Python, и, к счастью, они немного более самоуверенны, когда дело доходит до макета приложения.
Чтобы убедиться, что эта статья является полным и полноценным справочником по компоновке, я хотел выделить структуру, общую для этих фреймворков.
Джанго
Давайте пойдем в алфавитном порядке и начнем с Джанго. Одна из приятных особенностей Django заключается в том, что он создаст для вас скелет проекта после запуска django-admin startproject project
, где project
— это имя вашего проекта. Это создаст каталог в вашем текущем рабочем каталоге с именем , проект
, со следующей внутренней структурой:
проект/ │ ├── проект/ │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py │ └── manage.py
Это кажется немного пустым, не так ли? Где вся логика? Виды? Даже тестов нет!
В Django это проект, который связывает воедино другую концепцию Django, приложения. Приложения — это то место, где живут логика, модели, представления и т. д., и при этом они выполняют какую-то задачу, например ведут блог.
Приложения Django можно импортировать в проекты и использовать в разных проектах, они структурированы как специализированные пакеты Python.
Как и проекты, Django упрощает создание макетов приложений Django. После того, как вы настроите свой проект, все, что вам нужно сделать, это перейти к местоположению manage.py
и запустите python manage.py startapp app
, где app
— это имя вашего приложения.
В результате будет создан каталог с именем app
со следующим макетом:
приложение/ │ ├── миграции/ │ └── __init__.py │ ├── __init__.py ├── admin.py ├── apps.py ├── models.py ├──tests.py └── views.py
Затем его можно импортировать непосредственно в ваш проект. Подробная информация о том, что делают эти файлы, как использовать их для вашего проекта и т. д., выходит за рамки этого справочника, но вы можете получить всю эту информацию и многое другое в нашем руководстве по Django, а также в официальной документации Django.
Эта структура файлов и папок очень проста и соответствует основным требованиям для Django. Для любого проекта Django с открытым исходным кодом вы можете (и должны) адаптировать структуры из макетов приложений командной строки. Обычно я получаю что-то вроде этого во внешнем каталоге project/
:
проект/ │ ├── приложение/ │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ │ │ ├── миграции/ │ │ └── __init__. py │ │ │ ├── models.py │ ├──tests.py │ └── views.py │ ├── документы/ │ ├── проект/ │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py │ ├── статический/ │ └── style.css │ ├── шаблоны/ │ └── base.html │ ├── .gitignore ├── manage.py ├── ЛИЦЕНЗИЯ └── README.md
Более подробное обсуждение более сложных макетов приложений Django можно найти в этой ветке Stack Overflow. Документация проекта django-project-skeleton объясняет некоторые каталоги, которые вы найдете в ветке Stack Overflow. Всестороннее погружение в Django можно найти на страницах Two Scoops of Django, которые научат вас всем последним передовым методам разработки Django.
Для получения дополнительных руководств по Django посетите наш раздел Django на Real Python.
Колба
Flask — это веб-микрофреймворк Python. Одним из основных преимуществ является то, что его очень быстро настроить с минимальными накладными расходами. В документации Flask есть пример веб-приложения, который состоит менее чем из 10 строк кода и в одном скрипте. Конечно, на практике маловероятно, что вы будете писать такое маленькое веб-приложение.
К счастью, документация Flask налетает, чтобы спасти нас с предложенным макетом для их учебного проекта (веб-приложение для ведения блога под названием Flaskr), и мы рассмотрим его здесь из основного каталога проекта:
флакона₽/ │ ├── колба/ │ ├── ___init__.py │ ├── db.py │ ├── схема.sql │ ├── auth.py │ ├── blog.py │ ├── шаблоны/ │ │ ├── base.html │ │ ├── авторизация/ │ │ │ ├── login.html │ │ │ └── register.html │ │ │ │ │ └── блог/ │ │ ├── create.html │ │ ├── index.html │ │ └── update.html │ │ │ └── статический/ │ └── style.css │ ├── тесты/ │ ├── conftest.py │ ├── data.sql │ ├── test_factory.py │ ├── test_db.py │ ├── test_auth.py │ └── test_blog.py │ ├── venv/ │ ├── .gitignore ├── setup.py └── МАНИФЕСТ.in
Из этого содержимого видно, что приложение Flask, как и большинство приложений Python, построено на основе пакетов Python.
Примечание: Не видите? Быстрый совет по обнаружению пакетов — найти файл __init__. py
. Он находится в каталоге самого высокого уровня для этого конкретного пакета. В приведенном выше макете flaskr
— это пакет, содержащий модули db
, auth
и blog
.
В этом макете все живет в flaskr
, за исключением ваших тестов, каталога для ваших виртуальных сред и ваших обычных файлов верхнего уровня. Как и в других макетах, ваши тесты будут примерно соответствовать отдельным модулям, находящимся в пакете flaskr
. Ваши шаблоны также находятся в основном пакете проекта, чего не происходит с макетами Django.
Не забудьте также посетить нашу страницу Flask Boilerplate Github, чтобы увидеть более подробное приложение Flask и увидеть шаблон в действии здесь.
Чтобы узнать больше о Flask, ознакомьтесь со всеми нашими руководствами по Flask здесь.
Удалить рекламу
Выводы и напоминания
Теперь вы видели примеры макетов для различных типов приложений: одноразовые сценарии Python, устанавливаемые отдельные пакеты, более крупные приложения с внутренними пакетами, веб-приложения Django и веб-приложения Flask.
По завершении этого руководства у вас будут инструменты для успешного предотвращения блокировки кодировщика путем построения структуры вашего приложения, чтобы вы не смотрели на пустой холст, пытаясь понять, с чего начать.
Поскольку Python в значительной степени не имеет мнения, когда дело доходит до макетов приложений, вы можете настроить эти примеры макетов по своему усмотрению, чтобы они лучше соответствовали вашему варианту использования.
Я хочу, чтобы вы не только получили справку по макету приложения, но и поняли, что эти примеры не являются ни жесткими правилами, ни единственным способом структурировать ваше приложение. Со временем и с практикой вы разовьете способность создавать и настраивать свои собственные полезные макеты приложений Python.
Я пропустил вариант использования? У вас есть другая философия структуры приложения? Помогла ли эта статья предотвратить блокировку кодера? Дай мне знать в комментариях!
Смотреть сейчас Это руководство содержит связанный с ним видеокурс, созданный командой Real Python. Посмотрите его вместе с письменным учебным пособием, чтобы углубить свое понимание: Структурирование приложения Python
Структура пакета Python: Dead Simple Python: Структура проекта и импорт
Понравились статьи? Купить книгу! Dead Simple Python Джейсона С. Макдональда можно получить в No Starch Press.
Самое худшее в учебниках — это их простота, не так ли? Редко вы найдете один с более чем одним файлом, гораздо реже с несколькими каталогами.
Я обнаружил, что структурирование проекта Python является одним из наиболее часто упускаемых из виду компонентов обучения языку. Хуже того, многие разработчики ошибаются, натыкаясь на кучу распространенных ошибок, пока не придут к чему-то, что по крайней мере работает .
Хорошая новость: вам не обязательно быть одним из них!
В этом выпуске серии Dead Simple Python мы рассмотрим операторы import
, модули, пакеты и то, как собрать все вместе, не вырывая при этом волосы. Мы даже затронем VCS, PEP и дзен Python. Пристегнитесь!
Прежде чем мы углубимся в фактическую структуру проекта, давайте рассмотрим, как это вписывается в нашу систему контроля версий [VCS]… начиная с того факта, что вы нужен VCS! Вот несколько причин…
- Отслеживание каждого внесенного вами изменения,
- Выяснить, когда именно вы что-то сломали,
- Возможность видеть старые версии вашего кода,
- Резервное копирование кода и
- Сотрудничество с другими.
У вас есть множество возможностей. Git наиболее очевиден, особенно если вы не знаете, что еще использовать. Вы можете бесплатно разместить свой репозиторий Git на GitHub, GitLab, Bitbucket или Gitote и других. Если вам нужно что-то отличное от Git, есть десятки других вариантов, включая Mercurial, Bazaar, Subversion (хотя, если вы используете последний, ваши коллеги, вероятно, сочтут вас чем-то вроде динозавра).0003
Я буду спокойно предполагать, что вы используете Git для остальной части этого руководства, так как это то, что я использую исключительно.
После того, как вы создали репозиторий и клонировали локальную копию на свой компьютер, вы можете приступить к настройке проекта. Как минимум вам нужно создать следующее:
-
README.md
: Описание вашего проекта и его целей. -
LICENSE.md
: Лицензия вашего проекта, если он с открытым исходным кодом. (См. opensource.org для получения дополнительной информации о выборе.) -
.gitignore
: специальный файл, который сообщает Git, какие файлы и каталоги следует игнорировать. (Если вы используете другую систему контроля версий, этот файл имеет другое имя. Найдите его.) - Каталог с названием вашего проекта.
Верно… наши файлы кода Python на самом деле находятся в отдельном подкаталоге! Это очень важно, так как корневой каталог нашего репозитория будет сильно загроможден файлами сборки, скриптами упаковки, виртуальными средами и всеми другими вещами, которые на самом деле не являются частью исходного кода.
Просто для примера мы назовем наш вымышленный проект awesomething
.
Стиль Python в значительной степени регулируется набором документов под названием Предложения по улучшению Python , сокращенно PEP . Конечно, не все политически значимые лица на самом деле приняты — именно поэтому они называются «предложениями», — но некоторые из них. Вы можете просмотреть главный индекс PEP на официальном сайте Python. Этот индекс формально обозначается как PEP 0.
Прямо сейчас нас в основном интересуют PEP 8 , впервые созданный создателем языка Python Гвидо ван Россумом еще в 2001 году. Это документ, официально определяющий стиль кодирования, которому должны следовать все разработчики Python. Держите его под подушкой! Изучите его, следуйте ему, поощряйте других делать то же самое.
(Примечание: PEP 8 подчеркивает, что всегда есть исключения из правил стиля. Это руководство , а не предписание . ) Имена модулей»…
Модули должны иметь короткие имена со строчными буквами. В имени модуля можно использовать символы подчеркивания, если это улучшает читабельность. Пакеты Python также должны иметь короткие имена со строчными буквами, хотя использование символов подчеркивания не рекомендуется.
Мы скоро узнаем, что именно представляют собой модули и пакеты , а пока поймите, что модули названы по именам файлов , а пакеты названы по имени их каталога .
Другими словами, все имена файлов должны быть строчными, с символами подчеркивания, если это улучшает читаемость. Точно так же имена каталогов должны быть все в нижнем регистре, без подчеркивания, если вообще можно избежать . Другими словами…
- Сделайте это:
awesomething/data/load_settings.py
- НЕ Это:
awesomething/Data/LoadSettings.py
Я знаю, я знаю, многословный способ донести свою мысль, но, по крайней мере, я добавил немного бодрости духа в ваш шаг. ( Привет? Эта штука включена? )
Это может показаться разочаровывающим, но вот обещанные определения:
Любой файл Python ( .py
) представляет собой модуль , а набор модулей в каталоге представляет собой пакет .
Ну… почти. Есть еще одна вещь, которую вы должны сделать с каталогом, чтобы сделать его пакетом, и это вставить в него файл с именем __init__.py
. На самом деле вам не нужно помещать что-то в этот файл. Это просто должно быть там.
Есть и другие интересные вещи, которые вы можете сделать с __init__.py
, но это выходит за рамки этого руководства, поэтому прочитайте документацию, чтобы узнать больше.
Если вы сделаете забудете __init__.py
в своем пакете, он сделает что-то гораздо более странное, чем просто сбой, потому что это делает его неявным пакетом пространства имен . Есть несколько отличных вещей, которые вы можете сделать с этим специальным типом пакета, но я не буду вдаваться в это здесь. Как обычно, вы можете узнать больше, прочитав документацию: PEP 420: Пакеты неявного пространства имен.
Итак, если мы посмотрим на структуру нашего проекта, awesomething
на самом деле является пакетом, и он может содержать другие пакеты. Таким образом, мы можем назвать awesomething
нашим пакетом верхнего уровня , а все пакеты под его подпакетами . Это будет очень важно, как только мы перейдем к импорту материалов.
Давайте посмотрим на снимок моих реальных проектов, упущение
, чтобы получить представление о том, как мы структурируем материал…
упущение-git ├── ЛИЦЕНЗИЯ.md ├── пропуск │ ├── app.py │ ├── общий │ │ ├── classproperty.py │ │ ├── Константы.py │ │ ├── game_enums.py │ │ └── __init__.py │ ├── данные │ │ ├── data_loader.py │ │ ├── game_round_settings.py │ │ ├── __init__.py │ │ ├──scoreboard.py │ │ └── settings.py │ ├── игра │ │ ├── content_loader. py │ │ ├── game_item.py │ │ ├── game_round.py │ │ ├── __init__.py │ │ └── timer.py │ ├── __init__.py │ ├── __main__.py │ ├── ресурсы │ └── тесты │ ├── __init__.py │ ├── test_game_item.py │ ├── test_game_round_settings.py │ ├── test_scoreboard.py │ ├── test_settings.py │ ├── test_test.py │ └── test_timer.py ├── пилинтрк ├── README.md └── .gitignoreВойти в полноэкранный режимВыйти из полноэкранного режима
(Если вам интересно, я использовал программу UNIX дерево
, чтобы сделать эту маленькую диаграмму выше.) с четырьмя подпакетами: common
, data
, game
и test
. У меня также есть каталог resources
, но он содержит только звук игры, изображения и т. д. (здесь опущено для краткости). ресурсов
НЕ является пакетом, так как он не содержит __init__.py
.
В моем пакете верхнего уровня также есть еще один специальный файл: __main__. py
. Это файл, который запускается, когда мы запускаем наш пакет верхнего уровня напрямую через python -m omission
. Мы немного поговорим о том, что входит в этот __main__.py
.
Если вы когда-либо писали какой-либо осмысленный код Python, вы почти наверняка знакомы с оператором import
. Например…
импорт повторноВойти в полноэкранный режимВыйти из полноэкранного режима
Полезно знать, что когда мы импортируем модуль, мы фактически запускаем его. Это означает, что все операторы импорта
в модуле также выполняются.
Например, re.py
имеет несколько собственных операторов импорта, которые выполняются, когда мы говорим import re
. Это не означает, что они доступны для файла, который мы импортировали re
из , но это означает, что эти файлы должны существовать. Если (по какой-то маловероятной причине) enum.py
был удален в вашей среде, и вы запустили import re
, произойдет сбой с ошибкой. ..
Traceback (последний последний вызов):
Файл «weird.py», строка 1, в
import re
Файл «re.py», строка 122, в
import enum
ModuleNotFoundError: Нет модуля с именем ‘enum’
Естественно, прочитав это, вы можете немного запутаться. У меня были люди, которые спрашивали меня, почему внешний модуль (в этом примере re
) не может быть найден. Другие задавались вопросом, почему внутренний модуль ( enum
здесь) вообще импортируется, так как они не просили об этом прямо в своем коде. Ответ прост: мы импортировали re
, а тот импортирует enum
.
Конечно, приведенный выше сценарий является вымышленным: import enum
и import re
при нормальных обстоятельствах никогда не выйдут из строя, потому что оба модуля являются частью основной библиотеки Python. Это просто глупый пример. 😉
На самом деле существует несколько способов импорта, но большинство из них следует использовать редко, если вообще использовать.
Для всех приведенных ниже примеров мы представим, что у нас есть файл с именем smart_door.py
:
# smart_door.py защита закрыть(): print("Ааааааааааааааааааааааааааааааааааааа") деф открыть(): print("Спасибо, что сделали простую дверь очень счастливой.")Войти в полноэкранный режимВыйти из полноэкранного режима
Например, остальную часть кода этого раздела мы запустим в интерактивной оболочке Python из того же каталога, что и smart_door.py
.
Если мы хотим запустить функцию open()
, мы должны сначала импортировать модуль smart_door
. Самый простой способ сделать это…
import smart_door smart_door.open() smart_door.close()Войти в полноэкранный режимВыйти из полноэкранного режима
На самом деле мы бы сказали, что smart_door
является пространством имен из open()
и close()
. Разработчикам Python очень нравятся пространства имен, потому что они делают очевидным, откуда берутся функции и еще что-то.
(Кстати, не путайте namespace с неявным пакетом пространства имен . Это две разные вещи.)
Zen of Python , также известный как PEP 20, определяет философию языка Python . В последней строке есть оператор, который обращается к этому:
Пространства имен — это отличная идея — давайте сделаем больше таких!
Однако в определенный момент пространства имен могут стать проблемой, особенно с вложенными пакетами. foo.bar.baz.whatever.doThing()
просто уродлив. К счастью, у нас есть способ обойти необходимость использовать пространство имен каждый раз, когда мы вызываем функцию.
Если мы хотим иметь возможность использовать функцию open()
без необходимости постоянно предварять ее именем модуля, мы можем сделать это вместо этого…
из smart_door import open открытым()Войти в полноэкранный режимВыйти из полноэкранного режима
Однако обратите внимание, что ни close()
, ни smart_door. close()
не будет работать в этом последнем сценарии, потому что мы не импортировали функцию напрямую. Чтобы использовать его, нам нужно изменить код на этот…
из smart_door import open, close открытым() Закрыть()Войти в полноэкранный режимВыйти из полноэкранного режима
В этом ужасном кошмаре с вложенными пакетами мы теперь можем произнести из foo.bar.baz.whatever import doThing
, а затем просто использовать doThing()
напрямую. В качестве альтернативы, если нам нужно МАЛЕНЬКОЕ пространство имен, мы можем сказать из foo.bar.baz импортируйте что-нибудь
и скажите what.doThing()
.
Система импорта
невероятно гибкая.
Однако вскоре вы, вероятно, обнаружите, что говорите: «Но у меня в модуле сотни функций, и я хочу использовать их все!» Это тот момент, когда многие разработчики сходят с ума, делая это…
из smart_door import *Войти в полноэкранный режимВыйти из полноэкранного режима
Это очень, очень плохо! Проще говоря, он импортирует все в модуль напрямую, и это проблема. Представьте себе следующий код…
из импорта smart_door * из импорта gzip * открытым()Войти в полноэкранный режимВыйти из полноэкранного режима
Как вы думаете, что произойдет? Ответ таков: gzip.open()
будет вызываемой функцией, поскольку это последняя версия open()
, которая была импортирована и, таким образом, определена в нашем коде. smart_door.open()
было затененный — мы не можем назвать его как open()
, что означает, что мы вообще не можем его вызывать.
Конечно, поскольку мы обычно не знаем или, по крайней мере, не помним каждую функцию, класс и переменную в каждом импортируемом модуле, мы легко можем столкнуться с целой кучей беспорядка.
Zen of Python также учитывает этот сценарий…
Явное лучше, чем неявное.
Вам никогда не придется угадать откуда берется функция или переменная. Где-то в файле должен быть код, который явно говорит нам, откуда он взялся. Первые два сценария демонстрируют это.
Я также должен упомянуть, что более ранний сценарий foo.bar.baz.whatever.doThing()
— это то, что разработчики Python НЕ любят видеть. Также из Zen of Python …
Flat лучше, чем вложенный.
Некоторая вложенность пакетов — это нормально, но когда ваш проект начинает выглядеть как сложный набор матрешек, вы сделали что-то не так. Организуйте свои модули в пакеты, но делайте это достаточно просто.
Файловая структура проекта, которую мы создали ранее, вот-вот появится очень удобно . Вспомните мой проект omission
…
omission-git ├── ЛИЦЕНЗИЯ.md ├── пропуск │ ├── app.py │ ├── обыкновенный │ │ ├── classproperty.py │ │ ├── Константы.py │ │ ├── game_enums.py │ │ └── __init__.py │ ├── данные │ │ ├── data_loader.py │ │ ├── game_round_settings.py │ │ ├── __init__. py │ │ ├──scoreboard.py │ │ └── settings.py │ ├── игра │ │ ├── content_loader.py │ │ ├── game_item.py │ │ ├── game_round.py │ │ ├── __init__.py │ │ └── timer.py │ ├── __init__.py │ ├── __main__.py │ ├── ресурсы │ └── тесты │ ├── __init__.py │ ├── test_game_item.py │ ├── test_game_round_settings.py │ ├── test_scoreboard.py │ ├── test_settings.py │ ├── test_test.py │ └── test_timer.py ├── пилинтрк ├── README.md └── .gitignoreВойти в полноэкранный режимВыйти из полноэкранного режима
В моем модуле game_round_settings
, определенном omission/data/game_round_settings.py
, я хочу использовать свой класс GameMode
. Этот класс определен в omission/common/game_enums.py
. Как мне добраться до него?
Поскольку я определил omission
как пакет и организовал свои модули в подпакеты, на самом деле это довольно просто. В game_round_settings.py
я говорю…
из omission.common.game_enums импортировать GameModeВойти в полноэкранный режимВыйти из полноэкранного режима
Это называется абсолютным импортом . Он начинается с пакета верхнего уровня, omission
, и спускается в пакет common
, где ищет game_enums.py
.
Некоторые разработчики приходят ко мне с операторами импорта, больше похожими на из common.game_enums import GameMode
, и недоумевают, почему это не работает. Проще говоря, данные 9Пакет 0014 (где находится
game_round_settings.py
) ничего не знает о родственных пакетах.
Однако он знает о своих родителях. Из-за этого в Python есть что-то, называемое относительным импортом , что позволяет нам вместо этого делать то же самое...
из ..common.game_enums import GameModeВойти в полноэкранный режимВыйти из полноэкранного режима
..
означает «прямой родительский пакет этого пакета», что в данном случае является пропуском
. Таким образом, импорт возвращается на один уровень назад, спускается к common
и находит game_enums. py
.
Существует много споров о том, использовать ли абсолютный или относительный импорт. Лично я предпочитаю использовать абсолютный импорт, когда это возможно, потому что это делает код намного более читабельным. Однако вы можете составить собственное мнение. Единственная важная часть заключается в том, что результат очевиден - не должно быть никакой тайны, откуда что-то берется.
(Продолжение чтения: Настоящий Python — абсолютный и относительный импорт в Python
Здесь есть еще одна засада! В omission/data/settings.py
у меня есть эта строка:
из omission.data.game_round_settings import GameRoundSettingsВойти в полноэкранный режимВыйти из полноэкранного режима
Конечно, поскольку оба этих модуля находятся в одном пакете, мы должны просто сказать from game_round_settings import GameRoundSettings
, верно?
Неправильно! На самом деле не удастся найти game_round_settings. py
. Это связано с тем, что мы используем пакет верхнего уровня с пропуском
, что означает, что путь поиска (где Python ищет модули и в каком порядке) работает по-другому.
Однако вместо этого мы можем использовать относительный импорт:
из .game_round_settings import GameRoundSettingsВойти в полноэкранный режимВыйти из полноэкранного режима
В этом случае один .
означает «этот пакет».
Если вы знакомы с типичной файловой системой UNIX, это должно стать для вас понятным. ..
означает "назад на один уровень", а .
означает «текущее местоположение». Конечно, Python делает еще один шаг вперед: ...
означает "на два уровня назад", ....
- "на три уровня назад" и так далее.
Однако имейте в виду, что эти «уровни» здесь не просто каталоги. Это пакеты. Если у вас есть два разных пакета в простом каталоге, который НЕ является пакетом, вы не можете использовать относительный импорт для перехода от одного к другому. Для этого вам придется работать с путем поиска Python, и это выходит за рамки данного руководства. (См. документацию в конце этой статьи.)
Помните, я упоминал о создании __main__.py
в нашем пакете верхнего уровня? Это специальный файл, который выполняется, когда мы запускаем пакет непосредственно с помощью Python. Мой пакет omission
можно запустить из корня моего репозитория с помощью python -m omission
.
Вот содержимое этого файла:
из приложения импорта упущений если __name__ == '__main__': app.run()Войти в полноэкранный режимВыйти из полноэкранного режима
Да, это действительно так! Я импортирую свой модуль приложение
из пакета верхнего уровня упущение
.
Помните, я мог также сказать из . вместо этого импортируйте приложение
. В качестве альтернативы, если бы я хотел просто сказать run()
вместо app.run()
, я мог бы сделать из omission. app import run
или из .app import run
. В конце концов, не имеет большого значения с технической точки зрения, КАК я делаю этот импорт, если код читаем.
(Примечание: мы могли бы обсудить, логично ли для меня иметь отдельный app.py
для моей основной функции run()
, но у меня есть свои причины... и они выходят за рамки данного руководства.) __name__ == '__main__' оператор. В Python не так много шаблонов и — кода, который должен использоваться довольно универсально с небольшими изменениями или вообще без изменений — но это один из тех редких битов.
__name__
— это специальный строковый атрибут каждого модуля Python. Если бы я придерживался линии print(__name__)
вверху omission/data/settings.py
, когда этот модуль будет импортирован (и, следовательно, запущен), мы увидим распечатку «omission.data.settings».
Когда модуль запускается напрямую через python -m some_module
, этому модулю присваивается специальное значение __name__
: « main ».
Таким образом, if __name__ == '__main__':
фактически проверяет, выполняется ли модуль как основной модуль . Если это так, он запускает код под условием.
Вы можете увидеть это в действии и по-другому. Если бы я добавил следующее в конец app.py
…
if __name__ == '__main__': бежать()Войти в полноэкранный режимВыйти из полноэкранного режима
… Затем я могу выполнить этот модуль напрямую через python -m omission.app
, и результаты будут такими же, как python -m omission
. Теперь __main__.py
полностью игнорируется, а __name__
из omission/app.py
равно "__main__.py"
.
Между тем, если я просто запускаю python -m omission
, этот специальный код в app.py
игнорируется, поскольку его __name__
теперь снова omission.app
.
Видишь, как это работает?
Давайте посмотрим.
Каждый проект должен использовать систему контроля версий, например Git. Есть много вариантов на выбор.
Каждый файл кода Python (
.py
) является модулем .Распределите модули по пакетам . Каждый пакет должен содержать специальный файл
__init__.py
.Как правило, ваш проект должен состоять из одного пакета верхнего уровня, обычно содержащего вложенные пакеты. Этот пакет верхнего уровня обычно имеет то же имя, что и ваш проект, и существует в виде каталога в корне репозитория вашего проекта.
НИКОГДА НИКОГДА используйте
*
в операторе импорта. Прежде чем принять возможное исключение, дзен Python указывает: «Особые случаи не настолько особенные, чтобы нарушать правила».Используйте абсолютный или относительный импорт для ссылки на другие модули в вашем проекте.
Исполняемые проекты должны иметь
__main__. py
в пакете верхнего уровня. Затем вы можете напрямую выполнить этот пакет с помощьюpython -m myproject
.
Конечно, есть много более сложных концепций и трюков, которые мы можем использовать при структурировании проекта Python, но мы не будем обсуждать это здесь. Я настоятельно рекомендую прочитать документы:
- Ссылка на Python: система импорта
- Учебники по Python: модули
- PEP 8: руководство по стилю для Python
- PEP 20: дзен Python
- PEP 240: неявные пакеты пространства имен
Спасибо grym
, deniska
(Freenode IRC #python
), @cbrintnall и @rhymes (Dev) за предложенные исправления.
Организация и упаковка проектов Python
Свидание Теги питон / программирование / упаковкаСложный исследовательский проект часто опирается на множество различных программ и программных пакетов для достижения целей исследования. Важной частью научных вычислений является принятие решения о том, как организовать и структурировать код, который вы используете для исследований. Хорошо структурированный проект может сделать вас более эффективным и действенным исследователем. Это также ключевой компонент научной воспроизводимости.
Простое размещение всего вашего кода в репозиториях git не превратит волшебным образом кучу скриптов в красивый, хорошо организованный проект. Требуются более целенаправленные усилия.
Типы проектов¶
Не все проекты одинаковы. Основываясь на своем опыте, я классифицирую три различных типа сценариев «исследовательского кода», обычно встречающихся в науках о Земле.
- Исследовательский анализ : При изучении новой идеи часто достаточно одной тетради или сценария.
- Один документ : «Бумага» является стандартной единицей научной продукции. Код, относящийся к одному документу, обычно принадлежит друг другу.
- Повторно используемые программные элементы : В ходе наших исследовательских вычислений мы часто выявляем специализированные подпрограммы, которые хотим упаковать для повторного использования в других проектах или другими учеными. Здесь «скрипты» становятся «программным обеспечением».
В этой лекции представлены некоторые рекомендации для каждой категории.
Исследовательский анализ¶
Когда мы начинаем что-то новое, мы часто хотим просто начать программировать и быстро получить какие-то результаты. Это хорошо! Блокноты Jupyter — это идеальный формат для открытого исследовательского анализа, поскольку они полностью автономны: они инкапсулируют текст, код и рисунки. Если мы найдем что-то интересное или полезное, важно сохранить эти исследовательские блокноты.
Выделенный репозиторий github может быть излишним для одного файла. Вместо этого я рекомендую механизм github «gist» для сохранения и обмена такими «одноразовыми» блокнотами и фрагментами кода. Gists похожи на мини-репозитории, которыми можно легко поделиться и встроить. (Вы можете создать его прямо сейчас, перейдя на https://gist.github.com/.)
Вы можете загрузить любой файл (включая файл блокнота .ipynb
), перетащив его на основной веб-сайт. У вас есть выбор сделать вашу суть публичной или секретной. (Частной опции нет, но секретную информацию могут увидеть другие, только если вы дадите им URL-адрес.)
Существует также фантастически простой способ создания основных записей блокнота непосредственно из самого блокнота. Для этого требуется расширение jupyter gist от Min RK. Чтобы установить это расширение, введите в командной строке следующее:
установка jupyter nbextension https://rawgithub.com/minrk/ipython_extensions/master/nbextensions/gist.js --user jupyter nbextension включить суть
При перезагрузке ноутбука вы увидите маленькую кнопку со стрелкой на панели инструментов ноутбука. При первом нажатии на эту кнопку вам будет предложено ввести токен личного доступа Github. Перейдите по ссылке https://github.com/settings/tokens и выберите «Создать новый токен». Единственная «область действия», которая должна быть у вашего токена, — это «Создать сущность». После создания токена скопируйте и вставьте его обратно в диалоговое окно записной книжки. Теперь ваша записная книжка будет автоматически опубликована как суть, а ссылка на ее представление в nbviewer появится на панели инструментов. Если вы снова нажмете кнопку, суть обновится. Удивительно!
Я считаю, что это отличный способ быстро сохранять исследовательские блокноты и делиться ими с коллегами.
Научная воспроизводимость¶
Воспроизводимость является краеугольным камнем научного процесса. Однако сегодня часто можно прочитать, что наука переживает кризис воспроизводимости. Этот кризис может быть связан с возрастающей сложностью и стоимостью научного анализа, а также с растущим требованием публиковать как можно больше и как можно быстрее.
Сегодня почти все науки о Земле основаны на той или иной форме вычислений, от простого статистического анализа и подгонки кривой до продвинутого численного моделирования. В принципе, вычислительная наука должна быть высоко воспроизводимой. Тем не менее, это также приносит уникальные проблемы. Большой обзор проблем и лучших практик дан в Барба, Лорена А. (2017): Программа воспроизводимости группы Барба. фиговая доля. https://doi.org/10.6084/m9.figshare.4879928.v1. Многие предложения в этой лекции взяты или перефразированы из Barba (2017) .
Имейте в виду, что аудитория воспроизводимого проекта — это не только другие ученые… это вы , через год или всякий раз, когда вам нужно повторить и/или развить более раннюю работу. Большинство ученых опираются на свою докторскую степень. работать в течение десяти лет после выпуска. Дополнительное время, потраченное на воспроизводимость сейчас, сделает вас более продуктивным в долгосрочной перспективе.
Начнем с важного наблюдения.
Статья о вычислительной науке… это не сама стипендия, это просто реклама стипендии. Настоящая стипендия — это полная среда разработки программного обеспечения и полный набор инструкций, по которым были созданы рисунки.
Донохо, Д. и др. (2009), Воспроизводимые исследования в вычислительном гармоническом анализе, Comp. науч. англ. 11(1):8–18, doi: 10.1109/MCSE.2009.15
Сандве и др. (2013) дают некоторые конкретные рекомендации по вычислительной воспроизводимости.
- Для каждого результата отслеживайте, как он был получен
- Избегайте шагов ручного управления данными
- Заархивировать точные версии всех используемых внешних программ
- Управление версиями всех пользовательских сценариев
- Запишите все промежуточные результаты, по возможности, в стандартных форматах
- Для анализов, включающих случайность, обратите внимание на базовые случайные начальные значения
- Всегда храните необработанные данные за графиками
- Создание выходных данных иерархического анализа, позволяющих проверять слои с возрастающей детализацией
- Соедините текстовые операторы с базовыми результатами
- Предоставление общего доступа к скриптам, запускам и результатам
Эти рекомендации предполагают определенную структуру проекта.
Макет проекта¶
Воспроизводимая структура каталога проекта на одном листе бумаги может выглядеть примерно так
README.md ЛИЦЕНЗИЯ среда.yml данные/промежуточные_результаты.csv ноутбуки/process_raw_data.ipynb тетради/figure1.ipynb ноутбуки/figure2.ipynb блокноты /helper.py рукопись/manuscript.tex
Прекрасным примером такой статьи является проект Cesar Rocha Upper Ocean Seasonality: https://github.com/crocha700/UpperOceanSeasonality.
Программные элементы многократного использования¶
Научное программное обеспечение, возможно, можно разделить на две категории: одноразовые «скрипты», которые используются в очень специфическом контексте для выполнения очень специфической задачи (например, для создания определенного рисунка для статьи) и повторно используемые компоненты, которые инкапсулируют более общий рабочий процесс. Как только вы обнаружите, что повторяете одни и те же фрагменты кода во многих разных сценариях или проектах, пришло время начать создавать повторно используемые программные элементы.
Модули¶
Основным элементом повторного использования в python является модуль.
Модуль представляет собой файл .py
, который содержит объекты python, которые могут быть импортированы другими скриптами или блокнотами.
Давайте проиллюстрируем, как работают модули, на простом примере.
Обычной задачей в науках о Земле является вычисление расстояния по дуге большого круга между двумя точками на земном шаре. Есть несколько пакетов, которые могли бы сделать это за вас, но давайте напишем свой в качестве примера модуля.
Формула для расстояния по дуге большого круга:
(Обратите внимание, что эта формула требует 64-битной точности для достаточной точности.)
Давайте напишем модуль для выполнения этого вычисления. Откройте файл с именем gcdistance.py
в текстовом редакторе. (Файл должен находиться в том же каталоге, что и блокнот, в котором вы сейчас работаете.) Заполните его следующим кодом:
""" Модуль Python для вычисления расстояния по большому кругу """ импортировать numpy как np # приблизительный радиус Земли R = 6,371e6 def great_circle_distance (точка1, точка2): """Рассчитать расстояние по дуге большого круга между двумя точками. ПАРАМЕТРЫ ---------- точка 1: кортеж Пара координат (широта, долгота) в градусах точка2: кортеж Пара координат (широта, долгота) в градусах ВОЗВРАТ ------- расстояние: поплавок """ # распаковать координаты широта1, долгота1 = точка1 широта2, долгота2 = точка2 # распаковываем и переводим все в радианы phi1, lambda1, phi2, lambda2 = [np.deg2rad(v) для v в (точка1 + точка2)] # применить формулу # https://en.wikipedia.org/wiki/Great-circle_distance вернуть R*np.arccos( np.sin(phi1)*np.sin(phi2) + np.cos(phi1)*np.cos(phi2)*np.cos(лямбда2 - лямбда1))
Модуль начинается со строки документации, объясняющей, что он делает. Затем он содержит некоторые данные (просто константа R
) и одну функцию.
Теперь давайте импортируем наш модуль
В [4]:
import gcdistance помощь(gcdistance)
Справка по модулю gcdistance: ИМЯ gcdistance — модуль Python для вычисления расстояния по большому кругу ФУНКЦИИ great_circle_distance (точка1, точка2) Вычислить расстояние по дуге большого круга между двумя точками. ПАРАМЕТРЫ ---------- точка 1: кортеж Пара координат (широта, долгота) в градусах точка2: кортеж Пара координат (широта, долгота) в градусах ВОЗВРАТ ------- расстояние: поплавок ДАННЫЕ Р = 6371000,0 ФАЙЛ /Пользователи/rpa/Преподавание/research_computing/content/lectures/python/gcdistance.py
И давайте попробуем использовать его для расчета
В [2]:
gcdistance.great_circle_distance((60, 0), (50, 15))
Out[2]:
1460007.18981
Мы могли бы просто импортировать нужную нам функцию
In [5]:
from gcdistance import R, great_circle_distance р
Out[5]:
6371000.0
Если мы изменим модуль, нам нужно либо перезапустить наше ядро, либо перезагрузить модуль. (Обратите внимание, что функции, импортированные через из функции импорта модуля
невозможно перезагрузить. )
В [8]:
из importlib import reload перезагрузить (gcdistance)
Out[8]:
Модули — это простой способ совместного использования кода между разными скриптами или блокнотами в одном проекте. Файлы модуля должны находиться в том же каталоге, что и любой скрипт, который их импортирует! Это большое ограничение; это означает, что вы не можете использовать модули между разными проектами.
Когда у вас есть фрагмент кода, достаточно универсальный для совместного использования между проектами, вам нужно создать пакет.
Дополнительно: Стиль Python¶
Существует несколько абсолютных правил для стиля кода Python, но есть подробное рекомендуемое руководство по стилю. Некоторые особенно важные моменты:
- Длина строки не должна превышать 79 символов
- Имена модулей должны быть
строчными буквами
- Имена функций и переменных должны быть
lower_case_with_underscores
- Имена классов должны быть
CamelCase
Пакеты¶
Пакеты — это способ Python для инкапсуляции многократно используемых элементов кода для совместного использования с другими. Упаковка — огромная и сложная тема. Мы просто поцарапаем поверхность.
Мы уже взаимодействовали со многими пакетами. Просмотрите некоторые из их репозиториев github, чтобы изучить структуру большого пакета Python:
- NumPy: https://github.com/numpy/numpy
- Панды: https://github.com/pandas-dev/pandas
- Xarray: https://github.com/pydata/xarray
Примером меньшего и более понятного пакета является мой пакет xrft:
- xrft: https://github.com/rabernat/xrft
Все эти пакеты имеют общую базовую структуру. Представьте, что мы хотим превратить наш модуль расстояния по большому кругу в пакет. Это будет выглядеть так.
README.md ЛИЦЕНЗИЯ среда.yml требования.txt setup.py gcdistance/__init__.py gcdistance/gcdistance.py gcdistance/тесты/__init__.py gcdistancecs/тесты/test_gcdistance.py
Фактический пакет содержится в подкаталоге gcdistance
. Другие файлы являются вспомогательными файлами, которые помогают другим понять и установить ваш пакет. Вот обзор того, что они делают
Имя файла | Назначение |
---|---|
README.txt | Объясните, что это за пакет для |
ЛИЦЕНЗИЯ | Определяет юридические условия, в соответствии с которыми другие могут использовать пакет. Открытый исходный код приветствуется! |
environment.yml | Среда conda, описывающая зависимости пакета (подробнее) |
требования.txt | Файл, описывающий зависимости пакета для pip. (подробнее) |
setup.py | Специальный скрипт Python, который устанавливает ваш пакет. (подробнее) |
Сам пакет¶
Каталог gcdistance
— это фактический пакет. Любой каталог, содержащий файл __init__.py
, распознается Python как пакет. Этот файл может быть пустым, но он должен присутствовать. Из корневого каталога мы можем импортировать модуль из пакета следующим образом
из gcdistance import gcdistance
Да, это немного лишнее. Это связано с тем, что модуль gcdistance.py
имеет то же имя, что и каталог пакета gcdistance
.
Однако этот импорт будет работать только из родительского каталога. Он недоступен глобально из вашей среды Python.
setup.py
— это волшебный файл, который делает ваш пакет устанавливаемым и доступным в любом месте. Вот очень простой setup.py
из настройки импорта setuptools настраивать( имя = "gcрасстояние", версия = "0.0.1", автор = "Райан Абернати", пакеты = ['gcdistance'], install_requires=['numpy'], )
Для setup.py
имеется ошеломляющий набор параметров. Дополнительные поля необходимы, если вы хотите загрузить свой пакет в pypi (поэтому его можно установить через пункт
).
Чтобы запустить сценарий установки, мы вызываем из командной строки следующее:
python setup. py install
Файлы пакета копируются в каталог нашей библиотеки Python. Если мы планируем продолжать разработку пакета, мы можем установить его в «режиме разработчика» как
python setup.py develop
В этом случае файлы создаются символическими ссылками, а не копируются.
Тестирование¶
Программный пакет требует тестов, чтобы убедиться, что он работает правильно. У Мэтта Роклина есть отличный пост в блоге о том, почему мы должны писать тесты для нашего кода.
Тесты не должны быть сложными. Это просто проверка, чтобы убедиться, что ваш код делает то, что должен делать.
Чтобы добавить тесты в наш проект, мы создаем файл gcdistance/tests/test_gcdistance.py
. (Нам также нужен файл __init__.py
в каталоге tests
.) В приведенном ниже примере показан пример тестовой функции для нашего пакета.
импортировать numpy как np импортировать pytest из gcdistance.gcdistance импортировать great_circle_distance защита test_great_circle_distance(): # некоторые известные результаты # расстояние между двумя одинаковыми точками должно быть равно нулю утверждать great_circle_distance((20. , 30.), (20., 30.)) == 0 # проверить расстояние между Нью-Йорком и Лондоном Нью-Йорк = 40,7128, -74,0060 Лондон = 51,5074, 0,1278 dist_nyc_london = great_circle_distance(Нью-Йорк, Лондон) # очень строго, на самом деле не работает # утверждение dist_nyc_london == 5.587e6 # примерный вариант вышеописанного np.testing.assert_allclose (dist_nyc_london, 5.587e6, rtol = 1e-5) # теперь проверим, что мы не можем передать неправильное количество аргументов с pytest.raises(TypeError): great_circle_distance(1, 2, 3, 4)
Мы будем использовать pytest для запуска наших тестов. Если у вас не установлен pytest в вашей активной среде python, потратьте минуту, чтобы запустить pip install pytest
из командной строки. Теперь запустите
py.test -v
из корневого каталога вашего проекта. Вы должны увидеть уведомление о том, что тесты пройдены. Попробуйте поиграться с тестами, чтобы что-то не получилось.
Непрерывная интеграция с Travis CI¶
Вы можете настроить автоматическое тестирование вашего пакета, интегрировав github с Travis-CI.