Data &Przewodnik po szkoleniach AI 2021
Pobierz broszurę GoDataDriven, aby uzyskać pełny przegląd dostępnych szkoleń i podróży edukacyjnych inżynierii danych, data science, analityka danych i tłumacza analityki.
Gdy używasz pythona profesjonalnie, opłaca się skonfigurować swoje projekty
w spójny sposób. Pomaga to współpracownikom szybko zrozumieć
strukturę projektu i ułatwia im skonfigurowanie projektu
na ich maszynie. Kluczem do skonfigurowania projektu jest plik setup.py
.
W tym blogu zajmę się szczegółami tego pliku.
Gdzie zaczynamy
Zakładam, że masz już pakiet, który chcesz skonfigurować.
Nie musi to być gotowy pakiet – najlepiej utworzyć pliksetup.py
na długo przed ukończeniem projektu. Może to być nawet pusty pakiet;
upewnij się tylko, że folder pakietów istnieje
i zawiera plik o nazwie init.py
(który może być pusty).
Jeśli podążasz za strukturą
mojego kolegi Henka dla twojego projektu, twoja sytuacja wyjściowa powinna wyglądać tak:
example_project/├── exampleproject/ Python package with source code.│ ├── __init__.py Make the folder a package.│ └── example.py Example module.└── README.md README with info of the project.
Możesz mieć inne pliki lub foldery w swojej strukturze, na przykład
foldery o nazwach notebooks/
, tests/
lub data/
, ale nie są one wymagane.
Przypadek dla setup.py
Gdy już stworzysz pakiet taki jak ten, to prawdopodobnie
użyjesz części kodu w innych miejscach. Na przykład, możesz chcieć
zrobić to w notatniku:
from exampleproject.example import example_function
To zadziała, jeśli twoim bieżącym katalogiem roboczym jest example_project/
, ale w
wszystkich innych przypadkach python da ci wyjście takie jak:
ModuleNotFoundError: No module named 'exampleproject'
Mógłbyś powiedzieć pythonowi, gdzie ma szukać pakietu, ustawiając zmienną środowiskową PYTHONPATH
lub dodając ścieżkę do sys.path
,
ale jest to dalekie od ideału: wymagałoby to różnych działań na różnych
platformach, a ścieżka, którą musisz ustawić, zależy od lokalizacji twojego kodu.
Dużo lepszym sposobem jest zainstalowanie twojego pakietu używając setup.py
i pip
,
ponieważ pip
jest standardowym sposobem instalowania wszystkich innych pakietów, i jest zobowiązany
działać tak samo na wszystkich platformach.
Minimalny przykład
Więc jak wygląda plik setup.py
? Oto minimalny przykład0:
from setuptools import setup, find_packagessetup( name='example', version='0.1.0', packages=find_packages(include=))
Tutaj określamy trzy rzeczy:
- Nazwa pakietu, która jest nazwą, której
pip
użyje dla twojego pakietu.
Nie musi być taka sama jak nazwa folderu, w którym pakiet żyje
, chociaż może być myląca, jeśli nie jest. Przykładem, gdzie nazwa pakietu
i katalog nie pasują do siebie jest Scikit-Learn: instalujesz go
używającpip install scikit-learn
, podczas gdy używasz go importując zsklearn
. - Wersja twojego pakietu. To jest wersja, którą
pip
zgłosi, i jest używana
na przykład kiedy publikujesz swój pakiet na PyPI1. - Jakie pakiety dołączyć; w naszym przypadku jest to tylko
exampleproject/
.
Tutaj pozwalamysetuptools
dowiedzieć się tego
automatycznie2. Chociaż mógłbyś w zasadzie użyćfind_packages()
bez żadnych argumentów, może to potencjalnie spowodować dołączenie niechcianych pakietów
. To może się zdarzyć, na przykład,
jeśli dołączyłeś__init__.py
do swojegotests/
katalogu. Alternatywnie możesz także użyć argumentuexclude
, aby jawnie
zapobiec włączeniu testów do pakietu, ale jest to nieco
mniej solidne.
Teraz wszystko, co musisz zrobić, aby zainstalować swój pakiet, to uruchomić poniższe polecenie
z wnętrza example_project/
katalogu3:
pip install -e .
Tutaj .
odnosi się do bieżącego katalogu roboczego, który, jak zakładam, jest katalogiem
gdzie można znaleźć setup.py
. Flaga -e
określa, że chcemy zainstalować
w trybie edytowalnym, co oznacza
że kiedy edytujemy pliki w naszym pakiecie, nie musimy reinstalować pakietu
zanim zmiany wejdą w życie. Będziesz jednak musiał albo zrestartować
pythona, albo przeładować pakiet!
Gdy edytujesz informacje w samym setup.py
, w większości przypadków będziesz musiał przeinstalować
pakiet, a także jeśli dodasz nowe (pod)pakiety.
Gdy masz wątpliwości, nigdy nie zaszkodzi przeinstalować. Po prostu uruchom pip install -e .
ponownie.
Wymagania
Większość projektów ma pewne zależności. Najprawdopodobniej używałeś
pliku requirements.txt
już wcześniej, lub environment.yml
jeśli używasz conda
. Teraz, gdy tworzysz setup.py
, możesz określić swoje
zależności w argumencie install_requires
.
Na przykład, dla typowego projektu data science możesz mieć:
setup( name='example', version='0.1.0', packages=find_packages(include=), install_requires=)
Możesz określić wymagania bez wersji (PyYAML
), przypiąć wersję (pandas==0.23.3
), określić minimalną
wersję ('numpy>=1.14.5
) lub ustawić zakres wersji (matplotlib>=2.2.0,<3.0.0
). Te
wymagania zostaną automatycznie zainstalowane przez pip
kiedy zainstalujesz swój pakiet.
Extras-require
Czasami możesz mieć zależności, które są wymagane tylko w pewnych sytuacjach. Jako data scientist
często tworzę pakiety, których używam do trenowania modelu. Kiedy pracuję nad takim modelem interaktywnie
mogę potrzebować zainstalowanych matplotlib
i jupyter
, aby interaktywnie pracować z danymi
i tworzyć wizualizacje
wydajności modelu. Z drugiej strony, jeśli model działa w produkcji, nie chcę
instalować matplotlib
ani jupyter
na maszynie (lub kontenerze), na której trenuję
lub wnioskuję. Na szczęście setuptools
pozwala na określenie opcjonalnych zależności w extras_require
:
setup( name='example', version='0.1.0', packages=find_packages(include=), install_requires=, extras_require={ 'interactive': , })
Teraz jeśli zainstalujemy pakiet normalnie (pip install example
z PyPI lub pip install -e .
lokalnie)
zainstaluje on tylko zależności PyYAML
, pandas
i numpy
. Jednak gdy określimy
, że chcemy opcjonalne interactive
zależności (pip install example
lub pip install -e .
),
to matplotlib
i jupyter
będą również zainstalowane.
Skrypty i punkty wejścia
Głównym przypadkiem użycia większości pakietów pythona, które instalujesz z PyPI, jest zapewnienie funkcjonalności
którą można wykorzystać w innym kodzie pythona. Innymi słowy, możesz import
z tych pakietów.
Jako data scientist często tworzę pakiety, które nie są przeznaczone do użycia przez inny kod pythona, ale
są przeznaczone do zrobienia czegoś, na przykład do trenowania modelu. W związku z tym często mam skrypt pythona, który
chcę wykonać z wiersza poleceń.
Najlepszym sposobem4 na wyeksponowanie funkcjonalności pakietu w wierszu poleceń jest zdefiniowanie
pakietu entry_point
w taki sposób:
setup( # ..., entry_points={ 'console_scripts': })
Teraz możesz użyć polecenia my-command
z wiersza poleceń, które z kolei wykona main
funkcję wewnątrz exampleproject/example.py
. Nie zapomnij o reinstalacji – w przeciwnym razie komenda
nie zostanie zarejestrowana.
Testy
Kiedy piszesz jakikolwiek kod, gorąco zachęcam do pisania testów dla tego kodu. Do testowania
z pythonem proponuję użyć pytest
. Oczywiście nie chcesz dodawać pytest
do swoich zależności
w install_requires
: nie jest on wymagany przez użytkowników twojego pakietu. Aby mieć go zainstalowanego
automatycznie, gdy uruchamiasz testy, możesz dodać poniższe do swojego setup.py
:
setup( # ..., setup_requires=, tests_require=,)
Dodatkowo będziesz musiał stworzyć plik o nazwie setup.cfg
z następującą zawartością:
test=pytest
Teraz możesz po prostu uruchomić python setup.py test
, a setuptools
zapewni, że niezbędne zależności
są zainstalowane i uruchomi pytest
za ciebie! Zajrzyj tutaj, jeśli
chcesz podać argumenty lub ustawić opcje konfiguracyjne dla pytest
.
Jeśli masz jakieś dodatkowe wymagania dotyczące testowania (np. pytest-flask
), możesz je dodać do tests_require
.
Flake8
Personalnie uważam, że dobrym pomysłem jest uruchomienie Flake8, aby
sprawdzić formatowanie twojego kodu. Podobnie jak w przypadku pytest
, nie chcesz dodawać flake8
doinstall_requires
zależności: nie musi być zainstalowany, aby używać twojego
pakietu. Zamiast tego, możesz dodać go do setup_requires
:
setup( # ..., setup_requires=)
Teraz możesz po prostu uruchomić python setup.py flake8
. Oczywiście możesz także przypiąć wersję
pakietu flake8
(lub dowolnego innego pakietu) do setup_requires
.
Jeśli chcesz zmienić niektóre parametry konfiguracyjne Flake8 możesz dodać sekcję do
swojego setup.cfg
. Na przykład:
max-line-length=120
Dane pakietu
Czasami możesz chcieć dołączyć do swojego pakietu kilka plików niepythonowych. To
mogą być na przykład pliki schematu lub mała tabela wyszukująca. Bądź świadomy, że takie pliki
będą spakowane razem z twoim kodem, więc ogólnie złym pomysłem jest dołączanie
każdego dużego pliku.
Załóżmy, że mamy schema.json
w naszym projekcie, który umieszczamy w exampleproject/data/schema.json
.
Jeśli chcemy go włączyć do naszego pakietu, musimy użyć argumentu package_data
z setup
:
setup( # ..., package_data={'exampleproject': })
To sprawi, że plik zostanie włączony do pakietu. Możemy również wybrać dołączenie
wszystkich plików na podstawie wzorca, na przykład:
setup( # ..., package_data={'': })
To doda wszystkie *.json
pliki w każdym pakiecie, który napotka.
Nie próbuj teraz samemu ustalać położenia zainstalowanych plików, ponieważpkg_resources
ma kilka bardzo przydatnych funkcji ułatwiających:
-
pkg_resources.resource_stream
da Ci strumień pliku, podobnie jak obiekt
, który otrzymasz po wywołaniuopen()
, -
pkg_resources.resource_string
da Ci zawartość pliku jako ciąg znaków, -
pkg_resources.resource_filename
poda ci nazwę pliku (i rozpakuje
go do tymczasowego, jeśli jest zawarty w pakiecie zipped), jeśli dwie opcje
powyżej nie odpowiadają twoim potrzebom.
Na przykład, moglibyśmy wczytać nasz schemat używając:
from json import loadfrom pkg_resources import resource_streamschema = load(resource_stream('exampleproject', 'data/schema.json'))
Metadane
Jeśli zamierzasz opublikować swój pakiet, to prawdopodobnie chcesz dać swoim
potencjalnym użytkownikom trochę więcej informacji o twoim pakiecie, włączając w to opis,
nazwisko autora lub opiekuna, i adres url do strony domowej pakietu.
Pełną listę wszystkich dozwolonych metadanych można znaleźć w setuptools
docs.
Dodatkowo, jeśli zamierzasz publikować w PyPI, to możesz chcieć
automatycznie załadować zawartość swojego README.md
do long_description
,
i dostarczyć klasyfikatory, aby powiedzieć pip
jeszcze
więcej o swoim pakiecie.
Wrap-up
Ten blog powinien być dobrym punktem wyjścia do skonfigurowania większości twoich projektów python.
Jeśli chcesz przeczytać więcej o opakowaniach python zajrzyj
do dokumentów. Oto przykład setup.py
który łączy wszystkie części pokazane w tym blogu:
from setuptools import setup, find_packagessetup( name='example', version='0.1.0', description='Setting up a python package', author='Rogier van der Geer', author_email='[email protected]', url='https://blog.godatadriven.com/setup-py', packages=find_packages(include=), install_requires=, extras_require={'plotting': }, setup_requires=, tests_require=, entry_points={ 'console_scripts': }, package_data={'exampleproject': })
i towarzyszący setup.cfg
:
test=pytestmax-line-length=120
Popraw swoje umiejętności Pythona, ucz się od ekspertów!
W GoDataDriven oferujemy mnóstwo kursów Pythona od początkującego do eksperta, prowadzonych przez najlepszych profesjonalistów w tej dziedzinie. Dołącz do nas i podnieś poziom swojej gry w Pythona:
- Python Essentials – Świetny, jeśli dopiero zaczynasz przygodę z Pythonem.
- Certified Data Science with Python Foundation – Chcesz zrobić krok w górę od analizy danych i wizualizacji do prawdziwej nauki o danych? To jest właściwy kurs.
- Advanced Data Science with Python – Naucz się produkować swoje modele jak profesjonalista i używaj Pythona do uczenia maszynowego.
Przypisy
0: W tym blogu użyłem setuptools
do skonfigurowania mojego przykładowego projektu. Alternatywnie
można też użyć distutils,
które jest standardowym narzędziem do pakowania w pythonie, ale brakuje mu funkcji
takich jak find_packages()
funkcja i entry_points
.
Ponieważ używanie setuptools jest obecnie bardzo powszechne, a wiele z jego funkcji
może być szczególnie użytecznych, sugeruję, abyś używał setuptools.
1: Jeśli chcesz, aby wersja twojego pakietu była również dostępna wewnątrz pythona,
zobacz tutaj.
2: Mógłbyś również wypisać swoje pakiety ręcznie, ale jest to szczególnie podatne na błędy.
3: Alternatywnie mógłbyś uruchomić python setup.py install
, ale użycie pip
ma
wiele zalet, wśród których są automatyczna instalacja zależności i
możliwość odinstalowania lub uaktualnienia twojego pakietu.
4: Mógłbyś także użyć argumentu scripts
(zobacz dla
przykładu tutaj)
ale ponieważ wymaga to stworzenia skryptu powłoki Pythona, może nie działać
tak dobrze (lub w ogóle) na Windows.