"MetaClass", "new", " cls " i "super" - jaki jest dokładnie mechanizm?
Czytałem posty podobne do tych:
- czym jest metaklasa w Pythonie?
- jakie są Twoje (konkretne) przypadki użycia metaklas w Pythonie?
- Super Pythona jest fajny, ale nie można go używać
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
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:
Wezwanie do {[5] } jest / align = "left" / Por. W tym przypadku
super(MyType, cls)
rozwiązałobytype
; wywołanietype.__new__
lets Python complete it ' s normal instance etapy tworzenia.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 wcls.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.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'
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
-
"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
"jakie są Twoje (konkretne) przypadki użycia metaklas w Pythonie?". Podsumowując. Brak
"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.
Klasa ma 1 lub więcej superklas tworzących prosty łańcuch od mojej klasy do
object
.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.-
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.
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