Jaka jest różnica między klasami Starego i nowego stylu w Pythonie?
Jaka jest różnica między klasami Starego i nowego stylu w Pythonie? Czy jest jakiś powód, by w dzisiejszych czasach korzystać z zajęć w starym stylu?
9 answers
Z http://docs.python.org/2/reference/datamodel.html#new-style-and-classic-classes :
Do wersji Python 2.1, klasy w starym stylu były jedynymi dostępnymi dla użytkownika.
Pojęcie klasy (starego stylu) nie ma związku z pojęciem typu: jeśli
x
jest instancją klasy w starym stylu, tox.__class__
oznacza klasęx
, ale {[3] } jest zawsze<type 'instance'>
.Odzwierciedla to fakt, że wszystkie instancje w starym stylu, niezależnie od ich klasy, są realizowane z jednym wbudowanym typem, zwanym przykład.
W Pythonie 2.2 wprowadzono nowe klasy w celu ujednolicenia pojęć class I type . Klasa nowego stylu jest po prostu typem zdefiniowanym przez użytkownika, nie więcej, nie mniej.
Jeśli X jest instancją klasy nowego stylu, to
type(x)
jest zazwyczaj to samo cox.__class__
(choć nie jest to gwarantowane-a instancja klasy nowego stylu może nadpisać zwracaną wartość nax.__class__
).Główną motywacją do wprowadzenia klas nowego stylu jest dostarczenie zunifikowanego modelu obiektowego z pełnym meta-modelem .
[[9]}ma również szereg natychmiastowych korzyści, takich jak zdolność do podklasa większość typów wbudowanych, czyli wprowadzenie " deskryptorów", które umożliwiają obliczanie właściwości.Ze względu na kompatybilność, klasy są domyślnie nadal w starym stylu .
Klasy nowego stylu są tworzone przez podanie kolejna klasa w Nowym Stylu (tj. Typ) jako klasa nadrzędna, lub obiekt "Typ najwyższego poziomu", jeśli nie potrzebny jest inny rodzic.
Zachowanie klas nowego stylu różni się od zachowania klas starego stylu klas w wielu ważnych szczegółach oprócz tego, jaki rodzaj zwroty.
Niektóre z tych zmian są fundamentalne dla nowego modelu obiektowego, jak sposób wywoływania specjalnych metod. Inne to "poprawki", które nie mogły być zaimplementowane wcześniej dla problemów związanych z kompatybilnością, takich jak metoda kolejność rozwiązywania w przypadku wielokrotnego dziedziczenia.
Python 3 ma tylko klasy nowego stylu .
Bez względu na to, czy podklasujesz z
object
, czy nie, klasy są w Nowym Stylu w Pythonie 3.
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
2018-08-10 08:10:37
Klasy nowego stylu dziedziczą z obiektu lub z innej klasy nowego stylu.
class NewStyleClass(object):
pass
class AnotherNewStyleClass(NewStyleClass):
pass
Klasy w starym stylu nie.]}
class OldStyleClass():
pass
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
2011-12-20 22:12:38
Ważne zmiany zachowania pomiędzy klasami Starego i nowego stylu
- super Dodano
- MRO zmienione (wyjaśnione poniżej)
- deskryptory dodane
- nowe obiekty klasy stylu nie mogą być wywoływane, chyba że pochodzą z
Exception
(Przykład poniżej) -
__slots__
Dodano
MRO (Method Resolution Order) changed
Wspomniano o tym w innych odpowiedziach, ale oto konkretny przykład różnicy między klasycznym MRO i C3 MRO (stosowane w klasach nowego stylu).
Pytanie dotyczy kolejności, w jakiej atrybuty (które zawierają metody i zmienne członkowskie) są wyszukiwane w dziedziczeniu wielokrotnym.
Klasy Klasyczne najpierw przeszukują głębię od lewej do prawej. Zatrzymaj się na pierwszym meczu. Nie posiadają atrybutu __mro__
.
class C: i = 0
class C1(C): pass
class C2(C): i = 2
class C12(C1, C2): pass
class C21(C2, C1): pass
assert C12().i == 0
assert C21().i == 2
try:
C12.__mro__
except AttributeError:
pass
else:
assert False
New-style classes MRO jest bardziej skomplikowane do zsyntetyzowania w jednym angielskim zdaniu. Jest to szczegółowo wyjaśnione tutaj . Jedną z jego właściwości jest to, że klasa bazowa jest wyszukiwana tylko wtedy, gdy wszystkie jej klasy pochodne zostały już znalezione. Mają atrybut __mro__
, który pokazuje kolejność wyszukiwania.
class C(object): i = 0
class C1(C): pass
class C2(C): i = 2
class C12(C1, C2): pass
class C21(C2, C1): pass
assert C12().i == 2
assert C21().i == 2
assert C12.__mro__ == (C12, C1, C2, C, object)
assert C21.__mro__ == (C21, C2, C1, C, object)
Nowe obiekty klasy stylu nie mogą być wywoływane, chyba że pochodzą z Exception
Wokół Pythona 2.5 można było podnieść wiele klas, wokół Pythona 2.6 to zostało usunięte. W Pythonie 2.7.3:
# OK, old:
class Old: pass
try:
raise Old()
except Old:
pass
else:
assert False
# TypeError, new not derived from `Exception`.
class New(object): pass
try:
raise New()
except TypeError:
pass
else:
assert False
# OK, derived from `Exception`.
class New(Exception): pass
try:
raise New()
except New:
pass
else:
assert False
# `'str'` is a new style object, so you can't raise it:
try:
raise 'str'
except TypeError:
pass
else:
assert False
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:50
Klasy starych stylów są nadal nieznacznie szybsze do wyszukiwania atrybutów. Zazwyczaj nie jest to ważne, ale może być przydatne w Pythonie 2 wrażliwym na wydajność.kod x:
In [3]: class A: ...: def __init__(self): ...: self.a = 'hi there' ...: In [4]: class B(object): ...: def __init__(self): ...: self.a = 'hi there' ...: In [6]: aobj = A() In [7]: bobj = B() In [8]: %timeit aobj.a 10000000 loops, best of 3: 78.7 ns per loop In [10]: %timeit bobj.a 10000000 loops, best of 3: 86.9 ns per loop
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
2010-07-12 11:26:52
Guido napisał The Inside Story on New-Style Classes , naprawdę świetny artykuł o klasach new-style i old-style w Pythonie.
Python 3 ma tylko klasę new-style, nawet jeśli piszesz klasę old-style, jest ona pośrednio pochodna od object
.
Klasy nowego stylu mają pewne zaawansowane funkcje, których brakuje w klasach starego stylu, takie jak super
i Nowy C3 mro , niektóre magiczne metody itp.
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
2013-05-16 19:54:00
Oto bardzo praktyczna, Prawda / Fałsz różnica. Jedyną różnicą między dwiema wersjami poniższego kodu jest to, że w drugiej wersji osoba dziedziczy po obiekcie. Poza tym obie wersje są identyczne, ale z różnymi wynikami:
1) klasy w starym stylu
class Person():
_names_cache = {}
def __init__(self,name):
self.name = name
def __new__(cls,name):
return cls._names_cache.setdefault(name,object.__new__(cls,name))
ahmed1 = Person("Ahmed")
ahmed2 = Person("Ahmed")
print ahmed1 is ahmed2
print ahmed1
print ahmed2
>>> False
<__main__.Person instance at 0xb74acf8c>
<__main__.Person instance at 0xb74ac6cc>
>>>
2) klasy nowego stylu
class Person(object):
_names_cache = {}
def __init__(self,name):
self.name = name
def __new__(cls,name):
return cls._names_cache.setdefault(name,object.__new__(cls,name))
ahmed1 = Person("Ahmed")
ahmed2 = Person("Ahmed")
print ahmed2 is ahmed1
print ahmed1
print ahmed2
>>> True
<__main__.Person object at 0xb74ac66c>
<__main__.Person object at 0xb74ac66c>
>>>
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
2013-10-09 13:40:29
Klasy nowego stylu dziedziczą z object
i muszą być zapisane jako takie w Pythonie 2.2 (tj. class Classname(object):
zamiast class Classname:
). Podstawową zmianą jest ujednolicenie typów i klas, a przyjemnym efektem ubocznym jest to, że pozwala na dziedziczenie z typów wbudowanych.
Przeczytaj descrintro aby uzyskać więcej szczegółó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
2013-03-20 15:09:52
Nowe klasy stylu mogą używać super(Foo, self)
gdzie Foo
jest klasą, A {[2] } jest instancją.
super(type[, object-or-type])
Zwraca obiekt proxy, który deleguje wywołania metody do klasy nadrzędnej lub siostrzanej typu. Jest to przydatne przy dostępie do odziedziczonych metod, które zostały nadpisane w klasie. Kolejność wyszukiwania jest taka sama jak używana przez getattr (), z tym wyjątkiem, że sam typ jest pomijany.
I w Pythonie 3.x możesz po prostu użyć super()
wewnątrz klasy bez parametró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
2013-04-30 08:28:52
A raczej powinieneś zawsze używać klas nowego stylu, chyba że masz kod, który musi działać z wersjami Pythona starszymi niż 2.2.
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
2008-09-10 21:23:53