क्या कोई वर्ग घोषणा से विरासत में लेने का कोई कारण है object
?
मुझे बस कुछ कोड मिले जो ऐसा करता है और मुझे एक अच्छा कारण नहीं मिल सकता है।
class MyClass(object):
# class code follows...
क्या कोई वर्ग घोषणा से विरासत में लेने का कोई कारण है object
?
मुझे बस कुछ कोड मिले जो ऐसा करता है और मुझे एक अच्छा कारण नहीं मिल सकता है।
class MyClass(object):
# class code follows...
जवाबों:
क्या कोई वर्ग घोषणा से विरासत में लेने का कोई कारण है
object
?
पायथन 3 में, पायथन 2 और 3 के बीच संगतता के अलावा, कोई कारण नहीं । पायथन 2 में, कई कारण ।
पायथन 2.x में (2.2 से आगे) object
एक बेस-क्लास के रूप में उपस्थिति या अनुपस्थिति के आधार पर कक्षाओं की दो शैलियाँ हैं :
"क्लासिक" शैली वर्ग: उनके पास object
बेस क्लास के रूप में नहीं है :
>>> class ClassicSpam: # no base class
... pass
>>> ClassicSpam.__bases__
()
"नई" शैली की कक्षाएं: उनके पास प्रत्यक्ष या अप्रत्यक्ष रूप से (जैसे अंतर्निहित प्रकार से विरासत में ), 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'>,)
एक शक के बिना, जब आप एक क्लास लिखते हैं तो आप हमेशा नई शैली की कक्षाओं के लिए जाना चाहेंगे। ऐसा करने के कई गुण हैं, उनमें से कुछ को सूचीबद्ध करने के लिए:
वर्णनकर्ताओं के लिए समर्थन । विशेष रूप से, निम्नलिखित निर्माण विवरणकों के साथ संभव किए गए हैं:
classmethod
: एक विधि जो वर्ग को उदाहरण के बजाय एक अंतर्निहित तर्क के रूप में प्राप्त करती है।staticmethod
: एक विधि जो self
पहले तर्क के रूप में निहित तर्क को प्राप्त नहीं करती है।property
: किसी विशेषता को प्राप्त करने, स्थापित करने और हटाने के प्रबंधन के लिए कार्य बनाएँ।__slots__
: एक वर्ग की मेमोरी खपत को बचाता है और इसके परिणामस्वरूप तेजी से विशेषता का उपयोग होता है। बेशक, यह सीमाओं को लागू करता है ।__new__
स्थिर विधि: आप अनुकूलित कैसे नया वर्ग उदाहरणों बनाई गई हैं देता है।
विधि रिज़ॉल्यूशन ऑर्डर (एमआरओ) : किस क्रम में किसी क्लास के बेस क्लासेस को खोजा जाएगा कि किस विधि को कॉल करने की कोशिश की जाए।
एमआरओ, super
कॉल से संबंधित । इसे भी देखें, super()
सुपर माना जाता है।
यदि आपको विरासत में नहीं मिली है object
, तो इन्हें भूल जाइए। "नई" शैली वर्गों के अन्य भत्तों के साथ पिछली बुलेट बिंदुओं का अधिक विस्तृत विवरण यहां पाया जा सकता है ।
नई शैली की कक्षाओं के डाउनसाइड्स में से एक यह है कि वर्ग स्वयं अधिक मेमोरी की मांग कर रहा है। जब तक आप कई क्लास ऑब्जेक्ट नहीं बना रहे हैं, हालांकि, मुझे संदेह है कि यह एक मुद्दा होगा और यह सकारात्मकता के समुद्र में एक नकारात्मक डूब रहा है।
पायथन 3 में, चीजें सरल होती हैं। केवल नई-शैली की कक्षाएं मौजूद हैं (स्पष्ट रूप से कक्षाओं के रूप में संदर्भित) इसलिए, जोड़ने में एकमात्र अंतर object
आपको 8 और वर्णों में टाइप करने की आवश्यकता है। इस:
class ClassicSpam:
pass
पूरी तरह से समतुल्य है (उनके नाम के अलावा :-) इसके लिए:
class NewSpam(object):
pass
और इसके लिए:
class Spam():
pass
सब object
अपने में है __bases__
।
>>> [object in cls.__bases__ for cls in {Spam, NewSpam, ClassicSpam}]
[True, True, True]
पायथन 2 में: हमेशा object
स्पष्ट रूप से विरासत में मिलता है । भत्तों को प्राप्त करें।
पाइथन 3 में:object
यदि आप ऐसा कोड लिख रहे हैं, जो पैथॉन अज्ञेय होने की कोशिश करता है, तो उससे विरासत में मिला है , अर्थात उसे पायथन 2 और पायथन 3 दोनों में काम करने की आवश्यकता है। अन्यथा नहीं, यह वास्तव में कोई फर्क नहीं पड़ता क्योंकि पायथन आपके लिए इसे लागू करता है। परदे के पीछे।
object
। IIRC उस समय में एक बिंदु था जहां सभी बिलियन प्रकार नहीं थे जहां अभी तक नई शैली की कक्षाओं के लिए पोर्ट किया गया था।
object
। मेरे पास एक पाइथन 2.2.3 है जिसके आसपास और एक त्वरित जांच के बाद मुझे कोई अपराधी नहीं मिला लेकिन, मैं बाद में और स्पष्ट करने के लिए उत्तर दूंगा। रुचि होगी यदि आप एक उदाहरण मिल सकता है, हालांकि, मेरी जिज्ञासा शांत है।
object
, उसमें आधार है।
staticmethod
और classmethod
पुरानी शैली की कक्षाओं पर भी ठीक काम करते हैं। property
सॉर्टा पुरानी-शैली की कक्षाओं पर पढ़ने के लिए काम करता है , यह सिर्फ लिखने में अवरोधन करने में विफल रहता है (इसलिए यदि आप नाम पर असाइन करते हैं, तो उदाहरण दिए गए नाम की एक विशेषता प्राप्त करता है जो संपत्ति को छाया देता है)। यह भी ध्यान दें कि __slots__
विशेषता पहुंच की गति में सुधार ज्यादातर नुकसान के बारे में है कि नई-शैली वर्ग विशेषता पहुंच को नुकसान पहुंचाता है, इसलिए यह वास्तव में नई शैली की कक्षाओं का विक्रय बिंदु नहीं है (स्मृति बचत हालांकि एक विक्रय बिंदु है)।
अजगर ३
class MyClass(object):
= नई शैली की कक्षाclass MyClass:
= नई शैली की कक्षा (स्पष्ट रूप से विरासत में मिली object
)अजगर २
class MyClass(object):
= नई शैली की कक्षाclass MyClass:
= पुराने स्टाइल वर्गस्पष्टीकरण :
पायथन 3.x में आधार कक्षाओं को परिभाषित करते समय, आपको object
परिभाषा से छोड़ने की अनुमति है । हालांकि, यह समस्या को ट्रैक करने के लिए एक गंभीर मुश्किल के लिए दरवाजा खोल सकता है ...
पायथन ने पायथन 2.2 में नई शैली की कक्षाएं शुरू कीं, और अब तक पुरानी शैली की कक्षाएं वास्तव में काफी पुरानी हैं। पुरानी शैली की कक्षाओं की चर्चा 2.x डॉक्स में और 3.x डॉक्स में गैर-मौजूद है।
समस्या यह है कि, Python 2.x में पुरानी शैली की कक्षाओं के लिए सिंटैक्स, Python 3.x में नई-शैली कक्षाओं के लिए वैकल्पिक सिंटैक्स के समान है । पायथन 2.x अभी भी बहुत व्यापक रूप से उपयोग किया जाता है (जैसे GAE, Web2Py), और किसी भी कोड (या कोडर) को अनजाने में 3.x-शैली वर्ग परिभाषाओं को 2.x कोड में लाना कुछ गंभीर रूप से पुरानी आधार वस्तुओं के साथ समाप्त होने जा रहा है। और क्योंकि पुरानी शैली की कक्षाएं किसी के रडार पर नहीं हैं, इसलिए संभवत: उन्हें पता नहीं होगा कि उन्हें क्या मारा।
तो बस इसे लंबा करें और कुछ 2.x डेवलपर के आँसू बचाएं।
__metaclass__ = type
मॉड्यूल के शीर्ष पर रखा जाता है ( from __future__ import absolute_import, division, print_function
लाइन :-) के बाद ); यह Py2 में एक संगतता हैक है, जो डिफ़ॉल्ट रूप से मॉड्यूल के बाद के सभी वर्गों को नई शैली में परिभाषित करता है, और Py3 में, इसे पूरी तरह से अनदेखा किया जाता है (बस एक यादृच्छिक वैश्विक चर चारों ओर बैठा है), इसलिए यह हानिरहित है।
हाँ, यह एक 'नई शैली' वस्तु है। यह python2.2 में पेश किया गया एक फीचर था।
नई शैली की वस्तुओं में क्लासिक ऑब्जेक्ट के लिए एक अलग ऑब्जेक्ट मॉडल होता है, और कुछ चीजें पुरानी शैली की वस्तुओं के साथ ठीक से काम नहीं करेंगी, उदाहरण के लिए super()
, @property
और विवरणकर्ता। एक नई शैली वर्ग क्या है, इसके अच्छे विवरण के लिए इस लेख को देखें ।
मतभेदों के विवरण के लिए SO लिंक: पायथन में पुरानी शैली और नई शैली वर्गों के बीच क्या अंतर है?
object
पायथन 2 से विरासत में प्राप्त करने की आवश्यकता है
लर्न पायथॉन द हार्ड वे से इतिहास :
पायथन का एक वर्ग का मूल प्रतिपादन कई गंभीर तरीकों से टूट गया था। जब तक इस गलती को पहचान लिया गया तब तक यह पहले ही बहुत देर हो चुकी थी, और उन्हें इसका समर्थन करना था। समस्या को ठीक करने के लिए, उन्हें कुछ "नए वर्ग" शैली की आवश्यकता थी ताकि "पुरानी कक्षाएं" काम करती रहें लेकिन आप नए अधिक सही संस्करण का उपयोग कर सकते हैं।
उन्होंने फैसला किया कि वे एक "ऑब्जेक्ट" शब्द का उपयोग करेंगे, जिसे "क्लास" कहा जाएगा, जिसे आप एक क्लास बनाने के लिए विरासत में लेते हैं। यह भ्रामक है, लेकिन एक वर्ग "ऑब्जेक्ट" नामक वर्ग से एक वर्ग बनाने के लिए विरासत में मिला है, लेकिन यह वास्तव में एक वस्तु नहीं है इसका वर्ग है, लेकिन ऑब्जेक्ट से विरासत में प्राप्त करना मत भूलना।
केवल यह बताने के लिए कि नई शैली की कक्षाओं और पुरानी शैली की कक्षाओं के बीच अंतर क्या है, यह है कि नई शैली की कक्षाएं हमेशा object
वर्ग से या किसी अन्य वर्ग से विरासत में मिलती हैं object
:
class NewStyle(object):
pass
एक और उदाहरण है:
class AnotherExampleOfNewStyle(NewStyle):
pass
जबकि एक पुरानी शैली का आधार वर्ग इस तरह दिखता है:
class OldStyle():
pass
और एक पुरानी शैली का बच्चा वर्ग इस तरह दिखता है:
class OldStyleSubclass(OldStyle):
pass
आप देख सकते हैं कि एक पुरानी शैली का आधार वर्ग किसी अन्य वर्ग से विरासत में नहीं मिला है, हालाँकि, पुरानी शैली की कक्षाएं निश्चित रूप से, एक दूसरे से विरासत में मिली हैं। ऑब्जेक्ट से इनहेरिट करना इस बात की गारंटी देता है कि प्रत्येक पायथन वर्ग में कुछ कार्यक्षमता उपलब्ध है। पायथन 2.2 में नई शैली की कक्षाएं शुरू की गईं
object
को कॉल करना सभी भ्रामक नहीं है, और वास्तव में यह बहुत मानक है। स्मॉलटाक में एक रूट क्लास है Object
, और एक रूट मेटाक्लास नाम दिया गया है Class
। क्यों? क्योंकि, जैसा Dog
कि कुत्तों के लिए Object
एक वर्ग है, वस्तुओं के लिए एक वर्ग है, और Class
कक्षाओं के लिए एक वर्ग है। जावा, C #, ObjC, रूबी, और अधिकांश अन्य वर्ग-आधारित OO भाषाएँ जो लोग आज उपयोग करते हैं जिनकी जड़ वर्ग है Object
, केवल पायथन ही नहीं बल्कि नाम के रूप में भी कुछ भिन्नता का उपयोग करते हैं ।
हां, यह ऐतिहासिक है । इसके बिना, यह एक पुरानी शैली की क्लास बनाता है।
यदि आप type()
एक पुरानी शैली की वस्तु पर उपयोग करते हैं, तो आपको बस "उदाहरण" मिलता है। एक नई शैली की वस्तु पर आपको इसकी कक्षा मिलती है।
type()
पुरानी शैली की कक्षा में उपयोग करते हैं, तो आपको "टाइप" के बजाय "क्लासोबज" मिलता है।
वर्ग निर्माण कथन का वाक्य विन्यास:
class <ClassName>(superclass):
#code follows
किसी भी अन्य सुपरक्लेसेस की अनुपस्थिति में जिसे आप विशेष रूप से विरासत में लेना चाहते हैं, superclass
हमेशा होना चाहिए object
, जो कि पायथन में सभी वर्गों की जड़ है।
object
तकनीकी रूप से पायथन में "नई शैली" कक्षाओं की जड़ है। लेकिन आज नई शैली की कक्षाएं कक्षाओं की एकमात्र शैली के रूप में अच्छी हैं।
लेकिन, यदि आप object
कक्षाएं बनाते समय शब्द का स्पष्ट रूप से उपयोग नहीं करते हैं, तो जैसा कि दूसरों ने उल्लेख किया है, Python 3.x का स्पष्ट रूप से सुपरक्लास से विरासत में मिला है object
। लेकिन मुझे लगता है कि स्पष्ट रूप से निहित (नरक) से हमेशा बेहतर है