Magiczne metody __init__() i __new__() oraz __class__

0

Cześć,

właśnie jestem na etapie nauki klas, konkretnie metod magicznych.

  1. Spotkałam się z metodą __new__(), o której wiem tylko tyle, że ona się wywołuje przed __init__(). Działa podczas tworzenia obiektu i przekazuje parametry do __init__(). Próbowałam użyć ją z __init__():

    class ClassA():
        def __new__(self, imie, wiek):
            print("Tworze nowy obiekt")
    
        def __init__(self,imie, wiek):
            self.imiona = imie
            self.lat = wiek
            print("Przekazano parametry do init")        
    
    
    klasa = ClassA("Daria", 29)
    

    W rezultacie uzyskałam na konsoli napis "Tworze nowy obiekt", ale init nie wystartował. O co konkretnie chodzi z tym __new__() i __init__()?

  2. Spotkałam się z użyciem w klasie metody magicznej __class__. Poniżej podaję przykład:

    class ClassA:
    
      imie = 'Daria'
      wiek = 21
    
      def change(self):
        self.__class__.imie = 'Kasia'
        ClassA.wiek = 22
    

    Nie rozumiem, po co jest tutaj zastosowane __class__ i co ono robi. Użyłam zamiast self.__class__.imie = 'Kasia' to self.imie = 'Kasia' i uzyskałam ten sam wynik. Po co się to stosuje?

Pozdrawiam

2

__new__() w pythonie to prawdziwy konstruktor, którzy tworzy instancje obiektu. Wszystkie obiekty w pythonie są pochodnymi type. __init__() przypisuje jedynie właściwości temu obiektowi, czyli go inicjalizuje.

W Twoim przypadku init nic nie wyświetla, ponieważ nie tworzysz nowego obiektu. Dodaj coś w stylu

def __new__(cls, *args, **kwargs):
  return super(ClassA, cls).__new__(cls, *args, **kwargs)

i zadziała.

W drugim przypadku bazujesz na zmiennych klasowych a nie instancji. Te są takie same dla każdej z instancji. A stosuje się w rozmaitych przypadkach, chociażby jako zmienne globalne dla wszystkich obiektów konkretnej klasy. Poza tym są to zmienne statyczne, więc nawet nie musisz tworzyć instancji, żeby je wywołać.

2

moim zdaniem:
__new__ to alokator, w c++ odpowiednik to https://en.cppreference.com/w/cpp/memory/new/operator_new
__init__ to konstruktor

jak na mój gust to __new__ w pythonie jest jeszcze mniej przydatny niż operator new w c++. operator new może przydać się teoretycznie do obsługi pul obiektów, ale już w pythonie nie ma gwarancji (w specyfikacji) co do odpalania destruktorów/ finalizerów.

0

Moja rada: raczej unikaj __new__() oraz __class__. Może się zdarzyć, prędzej czy później że znajdziesz potrzebę żeby ich użyć - i wtedy sobie o nich przypomnisz; ale do standardowego developmentu 99.99% przypadków to __init__().

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