Wpis z mikrobloga

Tak się zastanawiam odnośnie mojego mikro crud'a w #python - Chciałem samymi funkcjami pozbierać inputy i konwertować je odpowiednio pod insert do sqla(z użyciem sqlalchemy), a później traktować produkt końcowy (składający się z 5 inputów) jako obiekt i poobrabiać go metodami (np zmiana liczby produktów). Zdałem sobie sprawę, że w sumie musiałbym pisać wszystkie założenia inputów jeszcze raz, co jest bez sensu. Zakładam, że muszę wybrać podejście - użycie OOP lub jego brak. Wolałbym to jednak zrobić obiektowo, bo to jednak coś zupełnie nowego dla mnie, a apkę piszę strcte po to, żeby się uczyć.

1) Czy są rzeczy, których nie powinno się pisać obiektowo? Jeżeli tak, to co na to wpływa?

2) Moje wstępne(zapewne błędne) założenie jest takie, że instancja będzie zawierała 5 zmiennych, które "zbiorę" w jakiś sposób wcześniej. Tutaj pytanie, zapewne wynikające z błędnego rozumienia oop - narazie stworzyłem @classmethod z inputem roboczym ale nie wiem, jak podłączyć pod to założenia (typu opis max 255 char, kategoria 1-12 itd).

Jeśli dobrze rozumiem - metody mają umożliwiać "operacje" na obiektach, jednak, skoro mam defakto 1 obiekt (dodawanie do listy zakupów produktu jeden po drugim) to czy to wszystko ma sens? #naukaprogramowania
  • 49
@michael93pl:

1. problem jest taki, że OOP jest utożsamiane z czymś więcej niż samym OOP - z całym szeregiem zasad, dobrych praktych, wzorców. Python jest specyficznym językiem, trzeba wprawy żeby wyczuć, kiedy opłaca się porzucić tradycyjne podejście OOP i projektować kod (lub jego fragment) inaczej - cała trudność w tym, że trzeba zachować te dobre praktyki z OOP

2. classmethod nie wywołujemy na instancji, tylko na klasie (przyjmuje jako pierwszy argument
@GlenPL: Django kiedyś ruszałem ale tylko jakąś prosta To Do List apke i chciałem to później zrobić. Najbardziej mi zależy na nauce właśnie całego OOP - gdzie nie spojrzę, widzę, że ktoś tworzy w OOP i jak najbardziej chce to poznać. Będę próbował przerabiać to po kolei i na pewno nie porzucę projektu, siedzę już nad nim 3 tydzień. Wyobraź sobie moje #!$%@?, że wczoraj doszedłem do wniosku, że to co
@michael93pl: Jeżeli dobrze rozumiem, w bazie masz kategorię i produkty w kategoriach. Ja bym się do tego zabrał w ten sposób, że popisałbym sobie funkcje (w pythonie łatwo z nich zrobić testy jednostkowe), które realizowałyby mi poszczególne scenariusze, które teraz realizujesz przy pomocy inputu. To ułatwi zauważenie funkcjonalności związanej ściśle z obiektami, IMVHO w tym przykładzie, masz dwie proste kartoteki (gdzie poza konstrukcją, odczytem, edycją i zapisem obiektu (takie CRUD właśnie)
@michael93pl: jeszcze na początek taki drobiazg:

new_name = input("Provide new name of your product")
product.change_name()
print(product.change_name())

tu newname powinno być parametrem (o ile jest sens pisania takiej metody) i powinno to być tak:

product.change_name(new_name)
print(product.get_name())

chociaż ja wolałbym napisać po prostu (szczególnie, że w ostatecznym kodzie tego nie będzie):

print(product.name)
@piotrb: Tak, mam wcześniej zdefiniowane kategorie w bazie, żeby user mógł wybrać tylko z "listy". O scenariuszach mówisz o tym, żeby funkcje nie zbierały strcte inputu, ale żeby input jakoś inaczej połączyć z tymi funkacjami, które będą sprawdzały poprawność inputu?

Co do tego changename(), newname to jakieś takie szybkie kombinowanie z metodami w ogóle to było z mojej strony, ciągle czytam/ oglądam różne tutoriale o OOP ale jak ze
@piotrb: O takim rozwiązaniu właśnie myślałem - tylko teraz "jakiś input" jest potrzebny, bo chcę, żeby to user tworzył swój produkt - np mój różowy wybiera nazwę, ilość, typ, kategorie, dodaje ewentualny opis, potem daje jej możliwość zmiany jakby coś popieprzyła (p2.changename('Rzodkiew') ), aż finalnie robię p2.save().

Nie wiem tylko jak tylko te inputy zebrać do formy , tak jak to zrobiłem wcześniej funkcjami ( bez oop) do:
final
product
@michael93pl: tzn. potrzebujesz wywołania __init__ ?:

final_product = Item(name, quantity, type, category, description)
i oczywiście oddzielaj (long z test2 będzie to łamać) pobieranie danych od obiektów, dane mogą przyjść skądkolwiek.
@piotrb: Najgorsze, że nawet nie wiem, czy tego potrzebuje czy nie -- "Muszę" zebrać jakoś wszystkie inputy, wcześniejsze moje rozwiązanie (jedyne, które atm znam, bez oop) to nawalenie wszystkich funkcji getname() itd, wrzucenie tego do gather() i tyle. Żeby bardziej zobrazować, czego potrzebuję: https://pastebin.com/BunWqKtb

Każdy input musi być jednak "przemielony" przez różne warunki (tak jak w main.py jest to rozwiązane zwykłymi funkcjami - np quantity to tylko int, category
@michael93pl: Ciężko się nauczyć OOP w pythonie. Tu nie ma statycznego typowania więc klasyczny polimorfizm jest niepotrzebny, nie ma prawdziwych interfejsów i klas abstrakcyjnych.

Jeśli chciałbyś się nauczyć OOP to polecam zmienić język a później dopiero wrócić do pythona. Chociaż wtedy możesz pewne rzeczy robić nie 'python way'
@michael93pl: quantity to raczej jako decimal, chyba, że nie dopuszczasz sprzedaży pół arbuza.
Mielenie, czyli walidacja powinna odbywać się w dwóch miejscach:
1. Przyjmowanie danych od użytkownika (z pliku, itd.),
2. Tworzenie obiektów (init).
w 1. dajesz ludzki komunikat,
w 2. dajesz wyjątek
to oczywiście spore uproszczenie, ale będę śledził kolejne wersję, to jeszcze coś podpowiem.
@gryzon_c: To mój pierwszy język i uczę się dopiero 3 miesiące ( jak zapewne widać ;p) i właśnie OOP mnie trochę pokonuję ale nie dam się. Czytałem docs ORM'u z którego korzystam dobry tydzień, mogę OOP uczyć się i kilka miesięcy ale to myknę kiedyś. Dzięki z radę jednak, o klasach abstrakcyjnych trochę czytałem i nawet "rozumiem", reszta nawet nic mi nie mówi :D
@piotrb: @GlenPL: Jak byście jeszcze dzisiaj znaleźli chwilę, to będę super wdzięczny !

Zakładam, że zbieranie inputów z @classmethod jest poprawne, może trochę lepiej się wyrażę w ten sposób - mam ja taki początek znowu: https://pastebin.com/tBSh07J7

Czy da się "podłączyć" na poziomie klasy (metodą czy inną magią ), żeby przy inpucie np. category działo się coś takiego? https://pastebin.com/yiaihfs7

Dzięki wielkie, teraz w pracy siedzę to robię to wszystko na online
nie ma prawdziwych interfejsów i klas abstrakcyjnych.


@gryzon_c: nie ma, ale są abc (Abstract Base Classes), co IMHO wystarczy. Nie ma za to wszystkich (IMHO zbędnych) obostrzeń - oraz niuansów (jak w C++).