"MetaClass", "new", " cls " i "super" - jaki jest dokładnie mechanizm?

Czytałem posty podobne do tych:

  1. czym jest metaklasa w Pythonie?
  2. jakie są Twoje (konkretne) przypadki użycia metaklas w Pythonie?
  3. Super Pythona jest fajny, ale nie można go używać
Ale jakoś się pogubiłem. Wiele nieporozumień jak:

Kiedy i dlaczego miałbym robić coś takiego?

# Refer link1
return super(MyType, cls).__new__(cls, name, bases, newattrs)

Lub

# Refer link2
return super(MetaSingleton, cls).__call__(*args, **kw)

Lub

# Refer link2
return type(self.__name__ + other.__name__, (self, other), {})

Jak działa super dokładnie?

Czym jest class registry i unregistry w link1 i jak dokładnie to działa? (Myślałem, że to ma coś wspólnego z singleton . Mogę się mylić, będąc z C tła. Mój styl kodowania jest nadal mieszanką Funkcjonalnego i OO).

Jaki jest przepływ instancji klasy (subclass, metaclass, super, type) i wywołania metody (

metaclass->__new__, metaclass->__init__, super->__new__, subclass->__init__ inherited from metaclass

) z dobrze skomentowanym kodem roboczym (choć pierwszy link jest dość blisko, ale nie mówi o słowie kluczowym cls i super(..) i rejestru). Najlepiej przykład z dziedziczeniem wielokrotnym.

P. S.: zrobiłem ostatnią część jako kod, ponieważ formatowanie przepełnienia stosu konwertowało tekst metaclass->__new__ do metaclass - > new

Author: Community, 2008-12-28

2 answers

OK, wrzuciłeś tu sporo pojęć do miksu! Mam zamiar wyciągnąć kilka konkretnych pytań masz.

Ogólnie rzecz biorąc, zrozumienie super, MRO i metclasses jest znacznie bardziej skomplikowane, ponieważ w ostatnich kilku wersjach Pythona zaszło wiele zmian w tym trudnym obszarze.

Własna dokumentacja Pythona jest bardzo dobrym odniesieniem i jest całkowicie aktualna. Istnieje IBM developerWorks Artykuł który jest w porządku jako wprowadzenie i ma podejście bardziej oparte na samouczkach, ale należy pamiętać, że ma pięć lat i spędza dużo czasu na mówieniu o starszych podejściach do meta-klas.

super to sposób dostępu do superklas obiektu. Jest bardziej złożone niż (na przykład) słowo kluczowe super Javy, głównie ze względu na wielokrotne dziedziczenie w Pythonie. Jak wyjaśnia Super-Klasa, użycie super() może prowadzić do niejawnego użycia łańcucha super-klas, porządku w tym jest zdefiniowana metodą kolejność rozdzielczości (MRO).

Możesz łatwo zobaczyć MRO dla klasy, wywołując mro() na klasie (nie na instancji). Zauważ, że meta-klasy nie znajdują się w hierarchii super-klas obiektu.

Thomas ' opis meta-klas tutaj jest doskonały:

Metaklasa jest klasą klasy. Jak klasa definiuje jak instancja klasy, metaklasy definiuje jak Klasa zachowuje się. A Klasa jest przykładem metaklasy.

W przykładach, które podajesz, oto co się dzieje:

  1. Wezwanie do {[5] } jest / align = "left" / Por. W tym przypadku super(MyType, cls) rozwiązałoby type; wywołanie type.__new__ lets Python complete it ' s normal instance etapy tworzenia.

  2. Ten przykład używa meta-klas aby wyegzekwować singleton. On overriding __call__ in the metaclass tak, że ilekroć Klasa instancja jest tworzona, przechwytuje to i może ominąć instancję stworzenie jeśli już istnieje (przechowywany w cls.instance). Uwaga że nadrzędne __new__ w metaclass nie będzie wystarczająco dobry, bo to się nazywa tylko wtedy, gdy Tworzenie klasy . / Align = "left" / __new__ na zajęciach będzie działać, jednak.

  3. Pokazuje to sposób na dynamiczne Utwórz klasę. On dołączanie nazwy dostarczonej klasy do utworzonej nazwy klasy, oraz dodawanie go do hierarchii klas też.

I ' m nie jestem do końca pewien, jakiego przykładu kodu szukasz, ale oto krótki przykład pokazujący meta-klasy, dziedziczenie i rozwiązywanie metod:

class MyMeta(type):
    def __new__(cls, name, bases, dct):
        print "meta: creating %s %s" % (name, bases)
        return type.__new__(cls, name, bases, dct)

    def meta_meth(cls):
        print "MyMeta.meta_meth"

    __repr__ = lambda c: c.__name__

class A(object):
    __metaclass__ = MyMeta
    def __init__(self):
        super(A, self).__init__()
        print "A init"

    def meth(self):
        print "A.meth"

class B(object):
    __metaclass__ = MyMeta
    def __init__(self):
        super(B, self).__init__()
        print "B init"

    def meth(self):
        print "B.meth"

class C(A, B):
    __metaclass__ = MyMeta
    def __init__(self):
        super(C, self).__init__()
        print "C init"

>>> c_obj = C()
meta: creating A (<type 'object'>,)
meta: creating B (<type 'object'>,)
meta: creating C (A, B)
B init
A init
C init
>>> c_obj.meth()
A.meth
>>> C.meta_meth()
MyMeta.meta_meth
>>> c_obj.meta_meth()
Traceback (most recent call last):
  File "mro.py", line 38, in <module>
    c_obj.meta_meth()
AttributeError: 'C' object has no attribute 'meta_meth'
 21
Author: James Brady,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:38

Oto bardziej pragmatyczna odpowiedź.

To rzadko ma znaczenie

  1. "Co to jest metaklas w Pythonie ". Podsumowując, type jest metaklasą wszystkich klas. Nie masz z tego praktycznie żadnego pożytku.

    class X(object):
        pass
    type(X) == type
    
  2. "jakie są Twoje (konkretne) przypadki użycia metaklas w Pythonie?". Podsumowując. Brak

  3. "Super Pythona jest sprytny, ale nie można go używać". Ciekawa notka, ale mało praktyczna wartość. Nigdy nie będziesz musiał rozwiązywać złożonych sieci dziedziczenia. Łatwo jest zapobiec powstawaniu tego problemu, używając explicity Strategy design zamiast wielokrotnego dziedziczenia.

Oto moje doświadczenie z ostatnich 7 lat programowania w Pythonie.

  1. Klasa ma 1 lub więcej superklas tworzących prosty łańcuch od mojej klasy do object.

  2. Pojęcie "klasy" jest zdefiniowane przez metaklasy nazwane type. Chciałbym rozszerzyć pojęcie "klasy", ale jak dotąd nigdy nie pojawiło się w praktyce. Ani razu. type zawsze robi to, co należy.

  3. Używanie super sprawdza się naprawdę dobrze w praktyce. Pozwala podklasie na odroczenie do klasy superklasy. Zdarza się, że pojawia się w tych przykładach metaklasy, ponieważ rozszerzają one wbudowaną metaklasę, type.

    Jednak we wszystkich sytuacjach podklasowych wykorzystasz super, aby rozszerzyć superklasa.

Metaklasy

Problem metaklasu jest taki:

  • Każdy obiekt ma odniesienie do jego definicji typu lub "klasy".

  • A class jest również obiektem.

  • Dlatego obiekt typu class ma odniesienie do jego typu lub "klasy". "Klasa ""klasy" jest metaklasą.

Ponieważ "klasa" nie jest obiektem wykonywalnym w C++, nie dzieje się tak w C++. Informatyka występuje w Javie, Smalltalku i Pythonie.

Metaklass definiuje zachowanie obiektu klasy.

  • 90% interakcja z klasą polega na poproszeniu klasy o utworzenie nowego obiektu.

  • 10% w tym czasie będziesz używał metod klasowych lub zmiennych klasowych ("statycznych" w języku C++ lub Java.)

Znalazłem kilka przypadków użycia metod na poziomie klasy. Nie mam prawie żadnych przypadków użycia dla zmiennych klasowych. Nigdy nie miałem takiej sytuacji. zmiana sposobu budowy obiektów.

 9
Author: S.Lott,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:16