Sınıf bildiriminin miras almasının bir nedeni var mı object
?
Sadece bunu yapan bazı kodlar buldum ve neden iyi bir neden bulamıyorum.
class MyClass(object):
# class code follows...
Sınıf bildiriminin miras almasının bir nedeni var mı object
?
Sadece bunu yapan bazı kodlar buldum ve neden iyi bir neden bulamıyorum.
class MyClass(object):
# class code follows...
Yanıtlar:
Sınıf bildiriminin miras almasının bir nedeni var mı
object
?
Python 3'te, Python 2 ve 3 arasındaki uyumluluk dışında bir sebep yok . Python 2'de birçok neden var .
Python 2.x'te (2.2'den itibaren), temel sınıf olarak varlığına veya yokluğuna bağlı olarak iki sınıf stili vardır object
:
"klasik" stil sınıfları: object
temel sınıfları yoktur:
>>> class ClassicSpam: # no base class
... pass
>>> ClassicSpam.__bases__
()
"yeni" stil sınıfları: temel sınıf olarak doğrudan veya dolaylı olarak (ör. yerleşik türden devralma ) object
:
>>> class NewSpam(object): # directly inherit from object
... pass
>>> NewSpam.__bases__
(<type 'object'>,)
>>> class IntSpam(int): # indirectly inherit from object...
... pass
>>> IntSpam.__bases__
(<type 'int'>,)
>>> IntSpam.__bases__[0].__bases__ # ... because int inherits from object
(<type 'object'>,)
Kuşkusuz, bir sınıf yazarken daima yeni stil sınıflarına gitmek isteyeceksiniz. Bunu yapmanın avantajları, bazılarını listelemek için çoktur:
Tanımlayıcılar için destek . Özellikle, aşağıdaki yapılar tanımlayıcılarla mümkün kılınmıştır:
classmethod
: Sınıfı örnek yerine örtük bir bağımsız değişken olarak alan bir yöntem.staticmethod
: Örtük bağımsız değişkeni self
ilk bağımsız değişken olarak almayan bir yöntem .property
: Bir özniteliğin alınmasını, ayarlanmasını ve silinmesini yönetmek için işlevler oluşturun.__slots__
: Bir sınıfın bellek tüketimini kaydeder ve daha hızlı öznitelik erişimi sağlar. Tabii ki, sınırlamalar getiriyor . __new__
Statik yöntemi: sınıf örnekleri nasıl oluşturulduğunu yeni özelleştirmenizi sağlar.
Yöntem çözünürlük sırası (MRO) : hangi yöntemin çağrılması gerektiğine karar verilirken bir sınıfın temel sınıfları aranır.
MRO ile ilgili super
çağrılar . Ayrıca bkz.super()
.
Eğer miras almazsan object
, bunları unut. Önceki mermi noktalarının daha ayrıntılı bir açıklaması ve diğer "yeni" stil sınıflarının avantajları burada bulunabilir .
Yeni stil sınıflarının dezavantajlarından biri, sınıfın kendisinin daha fazla bellek talep etmesidir. Pek çok sınıf nesnesi oluşturmadığınız sürece, bunun bir sorun olacağından şüphe duyuyorum ve bu bir pozitif denizde batıyor.
Python 3'te işler basitleştirilmiştir. Yalnızca yeni stil sınıfları vardır (açıkça sınıflar olarak adlandırılır), bu nedenle eklemedeki tek fark object
8 karakter daha yazmanızı gerektirir. Bu:
class ClassicSpam:
pass
tamamen aynıdır (isimlerinin dışında :-) buna:
class NewSpam(object):
pass
ve buna:
class Spam():
pass
Hepsi object
kendi içinde __bases__
.
>>> [object in cls.__bases__ for cls in {Spam, NewSpam, ClassicSpam}]
[True, True, True]
Python 2'de: her zaman object
açıkça . Faydaları al.
Python 3'te:object
Python agnostik olmaya çalışan bir kod yazıyorsanız, yani hem Python 2'de hem de Python 3'te çalışması gerekiyorsa devralın . Aksi halde Python sizin için eklediğinden gerçekten fark etmez kamera ARKASI.
object
. IIRC zaman içinde henüz yeni tip sınıflara taşınan tüm yerleşik tiplerin olmadığı bir nokta vardı.
object
. Etrafımda bir Python 2.2.3 var ve hızlı bir kontrolden sonra bir suçlu bulamadım, ancak daha açık hale getirmek için cevabı daha sonra yeniden yazacağım. Yine de bir örnek bulabilirseniz merakım olurdu.
object
temelde ne olduğunu açıklığa kavuşturmanın daha iyi olacağını düşünüyorum .
staticmethod
ve classmethod
eski tarz derslerde bile iyi çalışır. property
sorta eski stil sınıflarında okumak için çalışır , sadece yazma işlemlerine müdahale edemez (bu nedenle, isme atarsanız, örnek, özelliği gölgeleyen verilen adın bir niteliğini kazanır). Ayrıca, __slots__
erişim hızı özelliğindeki iyileşmenin çoğunlukla yeni stil sınıfı özellik erişiminin neden olduğu zararı geri almakla ilgili olduğunu unutmayın, bu yüzden yeni stil sınıflarının bir satış noktası değildir (bellek tasarrufları bir satış noktasıdır).
Python 3
class MyClass(object):
= Yeni stil sınıfıclass MyClass:
= Yeni stil sınıfı (üstü kapalı olarak miras alınır object
)Python 2
class MyClass(object):
= Yeni stil sınıfıclass MyClass:
= ESKİ TARZ SINIFIAçıklama :
Python 3.x'te temel sınıfları object
tanımlarken, tanımından bırakmanıza izin verilir . Ancak bu, izlemesi ciddi bir sorun için kapıyı açabilir ...
Python, Python 2.2'de yeni stil sınıfları tanıttı ve şimdiye kadar eski stil sınıfları gerçekten oldukça eski. Eski tarz sınıfların tartışılması 2.x belgelerine gömülür ve 3.x belgelerinde yoktur.
Sorun, Python 2.x eski stil sınıfları için sözdizimi Python 3.x yeni stil sınıfları için alternatif sözdizimi ile aynıdır . Python 2.x hala çok yaygın olarak kullanılmaktadır (örn. GAE, Web2Py) ve farkında olmadan 3.x tarzı sınıf tanımlarını 2.x koduna getiren herhangi bir kod (veya kodlayıcı) ciddi şekilde eskimiş temel nesnelerle sonuçlanacaktır. Ve eski stil sınıfları kimsenin radarında olmadığı için, onlara neyin çarptığını bilmeyeceklerdir.
Yani sadece uzun yoldan heceleyerek gözyaşları 2.x geliştirici kaydetmek.
__metaclass__ = type
modülün üstüne koymak ( from __future__ import absolute_import, division, print_function
satır :-) sonra ); Modüldeki daha sonra tanımlanmış tüm sınıfları varsayılan olarak yeni bir stil haline getiren Py2'de bir uyumluluk saldırısıdır ve Py3'te tamamen yok sayılır (sadece etrafta oturan rastgele bir global değişken), bu yüzden zararsızdır.
Evet, bu 'yeni bir stil' nesnesidir. Python2.2'de sunulan bir özellikti.
Yeni stil nesneler klasik nesnelere farklı bir nesne modeli var ve bazı şeyler örneği için, eski tarz nesnelerle düzgün çalışmaz super()
, @property
ve tarif. Yeni bir stil sınıfının ne olduğunun iyi bir açıklaması için bu makaleye bakın .
Farkların açıklaması için SO link: Python'daki eski stil ile yeni stil sınıfları arasındaki fark nedir?
object
Python 2'den miras almanız gerekir
Python'u Zor Yoldan Öğrenin Tarihi :
Python'un bir sınıfı orijinal olarak yorumlaması birçok ciddi şekilde kırıldı. Bu hatanın farkına varıncaya kadar çok geç olmuştu ve onu desteklemek zorundaydılar. Sorunu çözmek için, "eski sınıfların" çalışmaya devam edebilmesi için bazı "yeni sınıf" stilleri gerekiyordu, ancak yeni daha doğru sürümü kullanabilirsiniz.
Bir sınıf yapmak için miras aldığınız "sınıf" olmak için küçük harfli bir "nesne" kelimesi kullanmaya karar verdiler. Kafa karıştırıcıdır, ancak bir sınıf bir sınıf yapmak için "object" adlı sınıftan miras alır, ancak bu bir nesne değildir, aslında bir sınıftır, ancak nesneden miras almayı unutmayın.
Ayrıca, yeni stil sınıfları ile eski stil sınıfları arasındaki farkın ne olduğunu bilmenizi sağlamak için, yeni stil sınıfları her zaman object
sınıftan veya miras alınan başka bir sınıftan miras alır object
:
class NewStyle(object):
pass
Başka bir örnek:
class AnotherExampleOfNewStyle(NewStyle):
pass
Eski tarz bir temel sınıf şöyle görünürken:
class OldStyle():
pass
Ve eski tarz bir çocuk sınıfı şöyle görünür:
class OldStyleSubclass(OldStyle):
pass
Bir Eski Stil taban sınıfının başka bir sınıftan miras kalmadığını görebilirsiniz, ancak Eski Stil sınıfları elbette birbirinden miras alabilir. Nesneden devralma, her Python sınıfında belirli işlevlerin kullanılabilir olmasını garanti eder. Python 2.2'de yeni stil sınıfları tanıtıldı
object
o kadar kafa karıştırıcı değildir ve aslında oldukça standarttır. Smalltalk adlı bir kök sınıfı Object
ve adlı bir kök metasınıfı vardır Class
. Neden? Çünkü, tıpkı Dog
köpekler için olduğu gibi , Object
nesneler Class
için bir sınıftır ve sınıflar için bir sınıftır. Java, C #, ObjC, Ruby ve günümüzde kök sınıfı olan insanların kullandığı sınıf tabanlı OO dillerinin çoğu Object
, yalnızca Python'u değil, ad olarak bazı varyasyonları kullanır .
Evet, tarihi . Onsuz, eski tarz bir sınıf yaratır.
Eğer kullanırsanız type()
eski tarz nesne üzerinde, sadece "örneği" olsun. Yeni stil nesnesinde kendi sınıfını alırsınız.
type()
eski tarz bir sınıfta kullanıyorsanız, "type" yerine "classobj" alırsınız.
Sınıf oluşturma ifadesinin sözdizimi:
class <ClassName>(superclass):
#code follows
Özellikle miras almak istediğiniz diğer üst sınıfların yokluğunda, Python'daki tüm sınıfların kökü olan superclass
her zaman olmalıdır object
.
object
teknik olarak Python'daki "yeni stil" sınıflarının köküdür. Ancak bugün yeni stil sınıfları, tek sınıf tarzı olmak kadar iyidir.
Ancak, object
sınıfları oluştururken sözcüğü açıkça kullanmazsanız, diğerlerinin belirttiği gibi, Python 3.x örtük olarak object
üst sınıftan miras alır . Ama sanırım açık her zaman örtük olmaktan daha iyidir