क्या सभी पायथन वर्गों को वस्तु का विस्तार करना चाहिए?


129

मैंने पाया है कि निम्नलिखित काम दोनों:

class Foo():
    def a(self):
        print "hello"

class Foo(object):
    def a(self):
        print "hello"

क्या सभी पायथन वर्गों को वस्तु का विस्तार करना चाहिए? क्या वस्तु के विस्तार में कोई संभावित समस्याएँ नहीं हैं?


2
क्या आपस में class Foo():और कोई फर्क है class Foo:? जैसा कि मैंने देखा, दोनों पायथन 3 में काम करते हैं
वुल्फ

: यह अच्छी तरह से इस प्रश्न का उत्तर है stackoverflow.com/questions/4015417/...
nngeek

जवाबों:


117

पायथन 2 में, इनहेरिट नहीं करने से objectएक पुरानी शैली की क्लास बन जाएगी, जो अन्य प्रभावों के बीच, typeविभिन्न परिणाम देने का कारण बनती है:

>>> class Foo: pass
... 
>>> type(Foo())
<type 'instance'>

बनाम

>>> class Bar(object): pass
... 
>>> type(Bar())
<class '__main__.Bar'>

साथ ही कई उत्तराधिकार के नियम अलग - अलग हैं, जिन्हें मैं यहां संक्षेप में बताने की कोशिश नहीं करूंगा। सभी अच्छे प्रलेखन जो मैंने एमआई के बारे में देखे हैं, नई शैली की कक्षाओं का वर्णन करते हैं।

अंत में, पायथन 3 में पुरानी शैली की कक्षाएं गायब हो गई हैं, और विरासत से objectनिहित हो गया है। इसलिए, हमेशा नई शैली की कक्षाओं को प्राथमिकता दें, जब तक कि आपको पुराने सॉफ़्टवेयर के साथ बैकवर्ड कम्प्रेसर की आवश्यकता न हो।


68

पायथन 3 में, कक्षाएं objectस्पष्ट रूप से विस्तारित होती हैं , चाहे आप खुद से कहें या नहीं।

पायथन 2 में, पुरानी शैली और नई शैली की कक्षाएं हैं। संकेत करने के लिए एक वर्ग नई शैली है, आपको स्पष्ट रूप से विरासत में प्राप्त करना होगा object। यदि नहीं, तो पुरानी शैली के कार्यान्वयन का उपयोग किया जाता है।

आप आम तौर पर एक नई शैली की कक्षा चाहते हैं। objectस्पष्ट रूप से इनहेरीट । ध्यान दें कि यह पायथन 3 कोड पर भी लागू होता है जिसका उद्देश्य पायथन 2 के साथ संगत होना है।



4
बहुत सारे पायथन 3 कोड है जो फू (ऑब्जेक्ट) का उपयोग करता है:। क्या यह सिर्फ एक सम्मेलन है?
RFV5s

2
@RFVenter यह कोड हो सकता है जिसे पायथन 2 और 3 दोनों के तहत चलना चाहिए, जिस स्थिति में आपको स्पष्ट रूप से कक्षा 2 के तहत एक ही व्यवहार करने के लिए स्पष्ट रूप से ऑब्जेक्ट को उप-क्रम में रखने की आवश्यकता होती है
ब्लाबेरहाइडल

@blubberdiblub कि मुझे क्या संदेह है कि हमारी परियोजना विशेष रूप से अजगर 3.5 virtualenv पर चल रही है। मुझे लगता है कि कोड को अजगर 2 परियोजना से कॉपी किया जाना चाहिए था।
RFV5s

@RFVenter हाँ, यह एक और स्पष्टीकरण हो सकता है। और हां, अगर यह केवल पायथन 3.x है, तो ऑब्जेक्ट रेफरेंस से छुटकारा पाना ठीक है।
ब्लबरडाइब्लूब

17

अजगर 3 में आप तीन अलग-अलग तरीकों से एक क्लास बना सकते हैं और आंतरिक रूप से वे सभी समान हैं (उदाहरण देखें)। इससे कोई फर्क नहीं पड़ता कि आप एक वर्ग कैसे बनाते हैं, अजगर 3 में सभी कक्षाएं विशेष वर्ग से आती हैं जिन्हें ऑब्जेक्ट कहा जाता है । क्लास ऑब्जेक्ट पायथन में मौलिक वर्ग है और डबल-अंडरस्कोर विधियों, डिस्क्रिप्टर, सुपर () विधि, संपत्ति () विधि आदि जैसी बहुत सारी कार्यक्षमता प्रदान करता है।

उदाहरण 1।

class MyClass:
 pass

उदाहरण 2।

class MyClass():
 pass

उदाहरण 3।

class MyClass(object):
  pass

1
यह कड़ाई से सच नहीं है ... stackoverflow.com/questions/1238606/…
फिलिप एडलर

मुझे यकीन नहीं है कि मैं आपका अनुसरण कर रहा हूं। और हां, जब तक यह प्रासंगिक है, तब तक शायद ज्यादातर लोगों के लिए प्रासंगिक नहीं है।
फिलिप एडलर

@PhilipAdler यह आमतौर पर माना जाता है कि objectअंतर्निहित में संदर्भ बनाता है object। अगर हमें इस बात का ध्यान रखना चाहिए कि किसी भी CPython की अंतर्निहित पहचानकर्ता को प्रतिस्थापित किया जा सकता है तो हम डेटा मॉडल के बारे में कुछ अनुमान लगा सकते हैं। क्या यह गंभीरता से तर्क दिया जा सकता है कि strहमेशा एक तर्क के रूप में एक स्ट्रिंग को स्वीकार नहीं करता है क्योंकि कोई भी असाइन कर सकता है builtins.str = None?
नूनो एंड्रे

मैं इस दावे को देखता हूं कि यह "व्यापक रूप से ग्रहण किया गया" है, और मैं स्वीकार करता हूं कि यह एक धारणा है जिसे हर मौजूदा कार्यान्वयन बनाता है (यह भाषा की आवश्यकता नहीं है), यह मेरा अनुभव नहीं है कि बहुसंख्यक अजगर प्रोग्रामर I यह मान लिया है, इसके बारे में पता है, या यह भी माना जाता है। चाहे जो भी हो, यह दावा कि आमतौर पर यह माना जाता है, भले ही सच हो, मेरे दावे को अमान्य नहीं करता है कि समानता सख्ती से सच नहीं है।
फिलिप एडलर

1

हाँ, सभी पायथन वर्गों का विस्तार होना चाहिए (या बल्कि उपवर्ग, यह यहाँ पायथन है) वस्तु। जबकि आम तौर पर कोई गंभीर समस्या नहीं होगी, कुछ मामलों में (कई वंशानुक्रम वाले पेड़ों के साथ) यह महत्वपूर्ण होगा। यह पायथन 3 के साथ बेहतर संगतता भी सुनिश्चित करता है।


1
ठीक है, तकनीकी तौर पर अगर आपको क्लासिक क्लास नहीं मिलेगी, लेकिन इसका कोई वास्तविक लाभ नहीं है और यह वैसे भी अजगर 3 द्वारा समर्थित नहीं है
अधिकतम k।

मैं इस बारे में उत्सुक हूं कि यह पाइथन 3 के साथ संगतता में सुधार क्यों करता है। मेरी समझ से, python3 इसे ऑब्जेक्ट को स्वचालित रूप से विस्तारित करेगा भले ही आप इसे निर्दिष्ट न करें, है ना?
पॉल लो

2
@PaLLo राइट, लेकिन यदि आप स्पष्ट रूप से ऑब्जेक्ट से विरासत में लेते हैं, तो आपको पायथन 2 और पायथन 3 दोनों पर समान (नई शैली) व्यवहार मिलेगा। यह बदलने की बात नहीं है कि पायथन 3 कैसे काम करता है, यह आगे उपयोग करने की बात है
-पिथोन

यह सुझाव बहुत सुरुचिपूर्ण नहीं है, लेकिन यदि आप Python2 और Python3 को संबोधित करते हैं, तो यह प्रभावी लगता है। लेकिन व्यवहार में यह कितना प्रासंगिक है?
वुल्फ

@Wolf यह निर्भर करता है कि आप क्या कर रहे हैं। यदि आपके पास जटिल वंशानुक्रम वाले पेड़ हैं, तो यह काफी मायने रखता है। यदि आप चाहते हैं कि आपकी कक्षा एक डिस्क्रिप्टर हो, तो आपको नई शैली का उपयोग करना होगा। यदि आप अधिक गहराई से जानकारी चाहते हैं, तो आप stackoverflow.com/questions/54867/… से लिंक का अनुसरण कर सकते हैं।
pydsigner

1

जैसा कि अन्य जवाबों में शामिल है, ऑब्जेक्ट से विरासत 3 पायथन निहित है। लेकिन वे यह नहीं बताते हैं कि आपको क्या करना चाहिए और क्या सम्मेलन है।

पायथन 3 प्रलेखन उदाहरण सभी निम्नलिखित शैली का उपयोग करते हैं जो सम्मेलन है, इसलिए मेरा सुझाव है कि आप पायथन 3 में किसी भी भविष्य के कोड के लिए इसका पालन करें।

class Foo:
    pass

स्रोत: https://docs.python.org/3/tutorial/classes.html#class-objects

उदाहरण उद्धरण:

क्लास ऑब्जेक्ट दो प्रकार के संचालन का समर्थन करते हैं: संदर्भ और तात्कालिकता को विशेषता देते हैं।

विशेषता संदर्भ पायथन में सभी विशेषता संदर्भों के लिए उपयोग किए गए मानक सिंटैक्स का उपयोग करते हैं: obj.name। मान्य विशेषता नाम वे सभी नाम हैं जो कक्षा के नामस्थान में तब थे जब क्लास ऑब्जेक्ट बनाया गया था। इसलिए, यदि वर्ग परिभाषा इस तरह दिखती है:

class MyClass:
    """A simple example class"""
    i = 12345

    def f(self):
        return 'hello world'

एक और उद्धरण:

सामान्यतया, उदाहरण चर प्रत्येक उदाहरण के लिए विशिष्ट डेटा के लिए होते हैं और वर्ग चर वर्ग के सभी उदाहरणों द्वारा साझा किए गए विशेषताओं और विधियों के लिए होते हैं:

class Dog:

    kind = 'canine'         # class variable shared by all instances

    def __init__(self, name):
        self.name = name    # instance variable unique to each instance

0

python3 में कोई भिन्नता नहीं है, लेकिन python2 में विस्तार नहीं करने objectसे आपको एक पुरानी शैली की कक्षाएं मिलती हैं; आप पुरानी शैली की कक्षा में एक नई शैली की कक्षा का उपयोग करना चाहते हैं।


2
यह उत्तर उचित है, लेकिन अन्य उत्तरदाता तेजी से और / या बेहतर विस्तार से वहां गए हैं; यह उत्तर पृष्ठ पर किसी भी मूल्य को जोड़ नहीं रहा है क्योंकि यह खड़ा है।
मार्क अमेरी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.