Naucz się Pythona w weekend: Od zera do pełnego projektu
Jak szybko możemy nauczyć się nowego języka programowania? W tym artykule podzielimy się naszym weekendowym doświadczeniem z nauką Pythona poprzez budowanie pełnego projektu.
Jak szybko możemy nauczyć się nowego języka programowania? W tym artykule podzielimy się naszym weekendowym doświadczeniem z nauką Pythona poprzez budowanie pełnego projektu.
Logto, jako usługa tożsamości, zapewniającą płynne doświadczenie we wszelkich językach programowania i frameworkach, jest kluczowe. Często wymaga to tworzenia Software Development Kitów (SDK). Jednak kiedy dany język programowania nie znajduje się w naszym stosie technologicznym, a nasz zespół nie ma z nim doświadczenia, stworzenie solidnego SDK staje się wyzwaniem.
Python stanowił dla nas takie wyzwanie. Pomimo posiadania wielu użytkowników Pythona, brakowało nam SDK dla Pythona, co było stałym problemem. Zdeterminowany, aby to rozwiązać, zacząłem wypełniać ten brak.
Chociaż mam wieloletnie doświadczenie w programowaniu, Python wciąż jest dla mnie stosunkowo nieznanym terytorium. Chociaż bawiłem się Pythonem 2 przez krótki czas, aby napisać proste skrypty lata temu, moja wiedza była przestarzała. Niemniej jednak, nadszedł czas, aby zanurzyć się!
Z mojego doświadczenia wynika, że najskuteczniejszym podejściem do nauki nowego języka programowania jest zbudowanie pełnego projektu. Na szczęście nasz cel był prosty: stworzyć SDK Pythona dla aplikacji webowych dla Logto.
Zamiast od razu rzucić się do kodowania, podzielmy to na kroki. Oto lista:
Wygląda na to, że zadanie 1 wymaga najwięcej pracy, więc musimy potwierdzić zakres i kontynuować jego rozbicie. Ten krok jest kluczowy, aby zabezpieczyć granice projektu i uniknąć rozszerzania zakresu oraz nadmiernego inżynierowania.
Poprzednia praca naszego zespołu zaoszczędziła mi mnóstwo czasu:
Odniesienie się do tych zasobów dało mi jasny obraz tego, co należy zrobić. Chociaż szczegóły wykraczają poza zakres tego artykułu, przejdźmy dalej.
Używam Maca, więc Python jest już zainstalowany. Zastanawiałem się jednak, czy jest lepszy sposób zarządzania wersjami Pythona (słyszałem o problemach z kompatybilnością wersji), podobnie jak nvm dla Node.js. Szybko znalazłem pyenv i od razu zabrałem się do instalacji.
Następnym punktem programu był menedżer pakietów i zależności. Zazwyczaj są one połączone. Dlaczego więc nie skorzystać z pip (domyślnego dla Pythona)? Jeśli spojrzysz na requirements.txt, zobaczysz, że to tylko lista pakietów z wersjami. To nie wystarczy dla SDK, który może być używany przez inne projekty. Na przykład, możemy potrzebować dodać kilka pakietów do rozwoju, ale nie chcemy ich uwzględniać w finalnym SDK. requirements.txt jest zbyt prosty, aby to obsłużyć.
Jedną z korzyści wynikających z posiadania innych języków programowania w swoim stosie technologicznym jest możliwość wyszukania „odpowiednika w Pythonie”. Więc wpisałem „odpowiednik package.json dla Pythona” i znalazłem Poetry, doskonałego kandydata:
pyproject.toml, podobny do package.json w Node.js.Nowoczesne CLI często zawierają polecenie init przeznaczone dla nowych projektów. Podobnie jest z Poetry. Uruchomiłem polecenie i utworzyło ono dla mnie plik pyproject.toml.
W końcu nadszedł czas na napisanie kodu. Rozpoczęcie od klasycznego programu „Hello, World!” to zawsze dobry wybór. Kiedy uczysz się języka programowania, pełnowartościowe IDE nie zawsze są niezbędne; wystarczy edytor wspierany przez silną społeczność, taki jak VS Code.
Biorąc pod uwagę, że nasze SDK koncentruje się na aplikacjach webowych, rozpocząłem od prostego serwera webowego z użyciem popularnego frameworka Flask.
Wykorzystując możliwości Poetry, instalacja Flask może być łatwo dokonana za pomocą polecenia poetry add flask. Następnie, postępując zgodnie z oficjalnym przewodnikiem szybkiego startu Flask, napisałem plik 'hello.py' z następującym fragmentem kodu:
Uruchomienie serwera poprzez flask --app hello run i przejście do http://localhost:5000 w mojej przeglądarce dało pożądany wynik. Zadziałało!
Jako początkujący, nie spieszyłem się z pisaniem więcej kodu. Zamiast tego jest mnóstwo informacji do uzyskania z tego fragmentu kodu:
from x import y, aby zaimportować moduł lub klasę.new.@app.route działa jako dekorator rejestrujący funkcję jako obsługujący trasę.
def.Jak widać, jeśli spróbujemy zrozumieć każdą linię kodu zamiast „po prostu sprawić, żeby działało”, możemy się wiele z niej nauczyć. Tymczasem oficjalna dokumentacja Flask szczegółowo wyjaśniała ten fragment.
Nadszedł czas, aby rozpocząć projekt. Wkrótce zdefiniowałem klasę LogtoClient i spróbowałem dodać kilka właściwości oraz metod, aby lepiej poznać język:
Następnie zintegrowałem klasę z Flaskiem:
Zaczęło to przypominać prawdziwy projekt. Jednak czegoś mi brakowało: systemu typów.
Jako SDK, wprowadzenie systemu typów pomoże użytkownikom zrozumieć API i zmniejszy ryzyko błędów podczas tworzenia oprogramowania.
Python wprowadził wskazówki typów w wersji 3.5. Nie są one tak potężne jak w TypeScript, ale lepsze to niż nic. Dodałem kilka wskazówek typów do klasy LogtoClient:
Wygląda to znacznie lepiej. Jednak napotkałem problem, gdy doszło do bardziej złożonych typów, jak obiekt o z góry ustalonych kluczach. Na przykład, musimy zdefiniować klasę LogtoConfig, aby reprezentowała obiekt konfiguracji:
To wygląda okej, ale szybko napotkamy problemy z kodowaniem, dekodowaniem i walidacją obiektu z JSON-a.
Po pewnych badaniach zdecydowałem się na pydantic jako rozwiązanie. Jest to biblioteka do walidacji danych, która współpracuje ze wskazówkami dotyczącymi typów. Obsługuje różne funkcjonalności JSON bez uciążliwego kodu szablonowego.
Dzięki temu klasa LogtoConfig może zostać przepisana jako:
Nauczyło mnie to również, jak działa dziedziczenie klas w Pythonie poprzez dodanie nawiasów po nazwie klasy.
W SDK Logto musimy wykonywać zapytania HTTP do serwera Logto. Jeśli masz doświadczenie z JavaScriptem, fraza „piekło callbacków” prawdopodobnie brzmi ci znajomo. Jest to często spotykany problem przy pracy z operacjami asynchronicznymi. Współczesne języki programowania przedstawiają podobne rozwiązania, takie jak Promise lub coroutine.
Na szczęście Python ma wbudowane rozwiązanie async i await. Zanim ich użyjesz, upewnij się, że są kompatybilne z popularnymi frameworkami. W Flasku można to zrobić, instalując dodatkowy pakiet async i używając async def zamiast def:
Następnie możemy użyć await, aby poczekać na wynik operacji asynchronicznej.
Zapytania HTTP to ciekawy temat. Prawie każdy język programowania ma rozwiązanie natywne, ale deweloperzy zazwyczaj korzystają z biblioteki zewnętrznej dla ułatwienia użycia. Oto kilka przykładów:
XMLHttpRequest vs. fetch vs. axiosURLSession vs. AlamofireHttpURLConnection vs. OkHttpPodobnie jest z Pythonem. Moim wyborem było użycie aiohttp, ponieważ obsługuje async i await, a także jest popularny.
Przed Copilotem, teraz powinniśmy zajmować się żmudną częścią pisania logiki biznesowej. Dzięki pomocy konwencji SDK i innym SDK mogłem napisać opisowe komentarze dla każdej metody przed napisaniem kodu.
Zwiększa to czytelność kodu i pomaga deweloperom zrozumieć API bezpośrednio w IDE lub edytorze poprzez inteligencję kodu.
Na przykład, rozważmy metodę generateCodeChallenge, komentarze mogą wyglądać tak:
To doskonała podpowiedź dla Large Language Models (LLM): tworzenie definicji metod poprzez jasne komentarze. Copilot nie zawiódł:
Możliwe, że pewne poprawki będą potrzebne, ale to nie problem. Copilot z pewnością zmienił zasady gry.
W zasadzie tyle osiągnąłem pierwszego dnia. To był długi dzień, ale dzięki nowoczesnym narzędziom i technologiom było to znacznie lepsze, niż się spodziewałem.
Na podstawie pracy z pierwszego dnia, logika biznesowa była tworzona szybko. Jednak dla SDK to wciąż za mało. Oto zadania na drugi dzień:
Testy jednostkowe uratowały nas wiele razy, więc ich nie pominę. Oto typowe kwestie, które należy wziąć pod uwagę podczas pisania testów jednostkowych:
Z tymi pytaniami w głowie stwierdziłem, że wbudowany moduł unittest okazał się niewystarczający w niektórych przypadkach. Dlatego wybrałem pytest jako framework testowy. Obsługuje testy asynchroniczne i wydaje się wystarczająco dojrzały.
Podczas tej podróży odkryłem kilka interesujących nowych pojęć, takich jak fixture. Może to również przydać się w myśleniu podczas pisania kodu w innych językach.
Każdy język ma swoje własne style formatowania kodu. Osobiście, spójne formatowanie sprawia, że czuję się zadowolony i komfortowo; jest to również pomocne podczas przeglądów kodu i współpracy.
Zamiast przeszukiwać argumenty na temat „najlepszego” stylu, postanowiłem wybrać opiniowanego formatera i trzymać się go.
Black wygląda na dobry wybór. Jedynym problemem jest nieregulowany rozmiar tabulacji. Jednak to niewielki problem, postanowiłem się do niego dostosować.
Jako SDK, powinno być zgodne z popularnymi wersjami Pythona. Po przeszukaniu „statystyk użytkowania wersji Pythona”, postanowiłem użyć Python 3.8 jako minimalnej wersji.
Zaletą tego menedżera środowiska teraz się ukazuje. Mogę łatwo przełączać wersje Pythona, uruchamiając pyenv local 3.8 oraz poetry env use 3.8. Następnie mogłem uruchomić testy, aby ujawnić problemy z kompatybilnością.
Ciągła integracja gwarantuje jakość każdej zmiany kodu. Ponieważ nasz repozytorium było hostowane w GitHubie, GitHub Actions były naturalnym wyborem.
Główna przepływ pracy opiera się na prostych zasadach:
GitHub Actions ma dobrą społeczność, więc zbudowanie przepływu pracy zajęło tylko kilka minut.
Stosując strategię macierzy, możemy uruchomić przepływ pracy na różnych wersjach Pythona, a nawet na różnych systemach operacyjnych.
Ostatnim krokiem jest opublikowanie SDK. W przypadku pakietów publicznych można to zazwyczaj zrobić, przesyłając je do oficjalnego rejestru pakietów specyficznego dla danego języka. Na przykład, npm dla Node.js, PyPI dla Pythona, oraz CocoaPods dla Swift.
Poetry jest moją gwiazdą przewodnią. Wystarczy uruchomić poetry publish, aby opublikować pakiet w PyPI. To takie proste.
To była interesująca podróż. Bez wsparcia społeczności open-source byłoby znacznie trudniej. Wielkie brawa dla wszystkich współtwórców!
Oto kilka ogólnych wniosków:
Ostateczne wyniki możesz znaleźć w tym repozytorium. Dzięki tej samej strategii, szybko zbudowałem również Logto PHP SDK. Nie wahaj się dać nam znać, jeśli masz jakiekolwiek sugestie.
Mam nadzieję, że ten artykuł okaże się pomocny w nauce nowego języka programowania. Miłego kodowania!