Klasy w nowym stylu

Guido van Rossum, Unifying types and classes in Python 2.2 [Chodzi o zniesienie różnic pomiędzy typami wbudowanymi, a klasami stworzonymi przez użytkownika.]

http://python-history.blogspot.com/2010/06/inside-story-on-new-style-classes.html

https://rhettinger.wordpress.com/2011/05/26/super-considered-super/

http://stackoverflow.com/questions/222877/how-to-use-super-in-python

https://docs.python.org/2/howto/descriptor.html

WPROWADZENIE

W Pythonie 2.2 wprowadzono nowy rodzaj klas "w nowym stylu". Klasy zwyczajne nazywane są "klasycznymi" lub "w starym stylu". W Pythonie 3 wszystkie klasy są automatycznie tworzone w nowym stylu. Główne różnice pomiędzy tymi dwoma stylami klas dotyczą algorytmu wyszukiwania nazw w tzw. diamentowym wzorcu dziedziczenia ("najpierw poziomo od lewej do prawej, potem pionowo"), oraz mechanizmu wyszukiwania metod specjalnych dla operacji wbudowanych.

Klasy w nowym stylu dziedziczą z object. W Pythonie 3 wszystkie klasy są tworzone w nowym stylu.

Klasy w nowym stylu mogą używać niskopoziomowych konstruktorów __new__().

Klasy w nowym stylu mogą używać deskryptorów (łącznie z __slots__), stare nie mogą [a generalized way to customize attribute access].

Klasy w nowym stylu mogą używać metod statycznych i metod klasy.

Klasy w nowym stylu mogą używać dekoratorów (Py2.4+).

Klasy w nowym stylu mogą używać funkcji super [super(SomeClass, object-or-type). Delegowanie wywołania metody do przodka klasy. To jest szczególnie przydatne, gdy metoda została nadpisana].

Method Resolution Order (MRO): Klasy w nowym stylu przeszukują każdą klasę bazową tylko raz. Klasy w starym stylu przeszukują klasy bazowe od lewej do prawej, stosując rekurencję, co czasem prowadzi do niejednoznaczności (wielokrotne przeszukiwanie).


class OldStyle1: pass   # tylko Py2

class OldStyle2(OldStyle1): pass   # dziedziczenie

# Przeszukiwanie (karo).
#     Old1
#    /   \
# Old2   Old3
#    \   /
#     Old4
class Old1: pass

class Old2(Old1): pass

class Old3(Old1): pass

class Old4(Old2, Old3): pass

# Teraz MRO: Old4, Old2, Old1, Old3, Old1 [powtórnie].

#class NewStyle1(object): pass   # Py2 i Py3
class NewStyle1: pass   # tylko Py3

class NewStyle2(NewStyle1): pass   # dziedziczenie

# Przeszukiwanie (karo).
class New1(object): pass

class New2(New1): pass

class New3(New1): pass

class New4(New2, New3): pass

# Teraz MRO: New4, New2, New3, New1, object.