Pytania początkującego odnośnie języka

0

Czy w Pythonie istnieje coś takiego jak Internal class, packagescope class, chodzi mi o klasę, która jest widoczna tylko w paczce, W jaki sposób oznaczacie "punkty wejścia" w paczce? Czy istnieje coś takiego jak published z Perl.

Jak zrobić wirtualna metodę?

Jak oznaczyć klasę tylko do dziedziczenia ?

Czy istnieje jakaś konwencja, aby wskazać jaki typ parametru powinna przyjąć metoda? Bez pisania komentarza?

Jaki ORM dla Pythona?

1
  1. Nie
  2. https://stackoverflow.com/questions/4714136/how-to-implement-virtual-methods-in-python
  3. Zainteresuj sie Mixinami
  4. raczej nie
  5. np SQL Alchemy
1
._. napisał(a):

Czy w Pythonie istnieje coś takiego jak Internal class, packagescope class, chodzi mi o klasę, która jest widoczna tylko w paczce, W jaki sposób oznaczacie "punkty wejścia" w paczce? Czy istnieje coś takiego jak published z Perl.

Możesz jedynie kontrolować co jest dostępne po from foo import * poprzez zadeklarowanie __all__ w module foo. Nie zabroni to jednak bezpośredniego importowania "niewyeksportowanych" zmiennych, ani nawet odwoływania się do nich poprzez foo.zmienna. Wedle konwencji, zmienne o package scope poprzedza się underscorem, a prywatne - dwoma, np. _foo czy __foobar.

Jak zrobić wirtualna metodę?

W Pythonie wszystkie metody są wirtualne, w C++-owym tego słowa znaczeniu.

Jak oznaczyć klasę tylko do dziedziczenia ?

https://docs.python.org/3/library/abc.html
Oczywiście, jeśli będziesz chciał zrobić instancję takiej klasy, błąd poleci dopiero w runtime'ie.

Czy istnieje jakaś konwencja, aby wskazać jaki typ parametru powinna przyjąć metoda? Bez pisania komentarza?

Taka konwencja, która nie pozostawia wątpliwości ;) możesz użyć type hintów (https://docs.python.org/3/library/typing.html) lub po prostu nazwać zmienną po typie, którego powinna być, np. oczekując w funkcji parametru typu HttpRequest, nazwij parametr http_request.

Jaki ORM dla Pythona?

W Django - dołączony ORM, we wszystkich innych - SQLAlchemy.

0

Dzięki.

Może mi ktoś wyjaśnić co z kontenerami IOC w Pythonie, Czytałem o Dependency Injector, ale wydał mi się strasznie "toporny" nie dałoby się tego zrobić prościej za pomocą refleksji ? O co chodzi w tym, że zamiast kontenera powinno się używać "multiple inheritance and mixins" ?

1

Mi bardziej do gustu przypadła ta implementacja kontenera DI: https://pypi.org/project/Inject/
Refleksja w Pythonie za bardzo nie pomoże, bo nie ma tam silnego typowania. Jeśli będziesz miał dwie kompletnie niepowiązane klasy, przypadkiem posiadające pola i metody o takich samych sygnaturach, to skąd Python ma wiedzieć instancję której klasy chcesz tam wcisnąć? Type hinty są kompletnie opcjonalne, chociaż z tego co pamiętam, np. apistar używa właśnie ich do wstrzykiwania zależności: https://docs.apistar.com/api-guide/dependency-injection/
Jeśli chodzi o DI przy użyciu mixinów i multiple inheritance, to z tego co pamiętam chodziło o coś takiego:

from abc import abstractmethod

# abstract
class BaseUserService:
    @abstractmethod
    def create_user(self, username, password):
        pass

class ProductionUserService(BaseUserService):
    # TODO: production implementation here


class TestUserService(BaseUserService):
    # TODO: in-memory implementation here

class ProductionUserServiceInjector:

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._user_service = ProductionUserService()

class TestUserServiceInjector:

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._user_service = TestUserService()


class BaseUserController(HttpController):
    _user_service = None  # inject

    def create_user(self, data):
        self._user_service.create_user(data.username, data.password)

# real http request handler
class ProductionUserController(BaseUserController, ProductionUserServiceInjector):
    pass

# test request handler
class TestUserController(BaseUserController, TestUserServiceInjector):
    pass
0

Żadnego injecta, nie stosuje się ioc w pythonie, jest dynamiczny I ma silny mechanizm wielodziedziczenia I mixinów, który się stosuje. Nie podoba mI się zaproponowane tutaj rozwiązanie ;)

To bardziej wygląda jak service locator.

No właśnie nie potrafię sobie tego wyobrazić co to są te "mixinery".

Jakie widzicie zalety i wady tych dwóch podejść (IOC i "mixinery") ze świata silnie typowanych języków i dynamicznych?

1

Mixin czyli to jest taka klasa rodzic ktora sluzy tylko do tego zeby ja odziedziczyc mozesz np zaimplementowac w niej jakas metode zeby potem ja odziedziczyc i nadpisac w klasie Dziedziczonej

0

Czyli taki jakby interface, Więc w Pythonie każda klasa z samymi metodami abstrakcyjnymi jest "interfejsem"?

Dlaczego w Pythonie nie ma Switcha ?

Czy są problemy z pisaniem aplikacji wielowątkowych?

1

Python switcha improwizuję w trochę inny sposób - w moim przekonaniu sensownieszy, zmuszający do podziału na funkcje.

Są dwie wersje, z lambdą do przekazywania argumentów i bez niej, do wywołania.


def foo1():
    print(1)

def foo2():
    print(2)

def main():
    switch = {  1: foo1,
                2: foo2}

    select = int(input("Select: "))

    switch.get(select)() #W drugim nawiasie dajesz argumenty jeśli są identyczne dla każdej funkcji.

main()

A tu drugi przykład argumentowych funkcji:


def foo1(a, b, c):
    print(1, a, b, c)

def foo2(b, c):
    print(2, b, c)
    c+=1

def main():
    a=2
    b=3
    c=4

    switch = {  1: lambda a1=a, b1=b, c1=c: foo1(a1,b1,c1),
                2: lambda b1=b: foo2(b1, c)}

    select = int(input("Select: "))

    c+=1
    switch.get(select)() #Tu wywołujesz całego "switch'a"
    switch.get(select)() #Tu wywołujesz całego "switch'a"
    #Argumenty jakie wykorzystuje funkcja, definiuje to jak użyjesz lambdy,
    #czy dasz argument po prostu, czy nadasz mu stałą wartość do lambdy, co widać w przykładzie foo1 i foo2.
    #Dla foo1 jest już przypisane 4 w momencie tworzenia switch'a.
    #Dla foo2 jest wykorzystywana zmienna c, niezależnie od tego jak się zmieni w trakcie programu.
    
    #Wszystkie wartości są tylko pobierane do funkcji bez możliwości ich zmiany.
    #Istnieje jeszcze jeden sposób jeśli chcemy modyfikować te zmienne, ale niestety aktualnie nie przypominam sobie tego z wyjątkiem słowników. Bo w klasach to najprościej wykorzystywać pierwszą wersję i parametr self.

main()
0

Co do tego switch-a to jest taka teorie ze switch sam w sobie "przeczy" idei polimorfizmu.
Ogólnie się z tym zgadzam i unikam na ile to możliwe.
W Pythonie poszli o krok dalej z tym switchem i zwyczajnie explicite go "nie ma" co można interpetować jako potwierdzenie teorii z 1 zdania.

0

Możesz jedynie kontrolować co jest dostępne po from foo import * poprzez zadeklarowanie all w module foo. Nie zabroni to jednak bezpośredniego importowania "niewyeksportowanych" zmiennych, ani nawet odwoływania się do nich poprzez foo.zmienna. Wedle konwencji, zmienne o package scope poprzedza się underscorem, a prywatne - dwoma, np. _foo czy __foobar.

A jeśli chcę, żeby cała klasa była package scope?

Nie przeszkadza wam to? Dla mnie to co najmniej dziwne.
Jeśli projektuje paczkę dla kolegi to jak wskazać która klasa jest tą wejściową, która steruje paczką.?

1

A nie wystarczy Ci dorzucenie odpowiednich klas do

__init__.py 

np: opisano to tutaj: CLICK

1

Jest na to jakaś konwencja? Co o tym myślicie?
__Application to wewnętrzna paczka

__init__.py
from Crud.__Application.Fasada import AppFasada as Fasada
from Crud.__Application import DTO as DTO

Z jakimi bibliotekami PyPy może mieć problem ?

1 użytkowników online, w tym zalogowanych: 0, gości: 1