2009-07-02 16 views
17

अजगर में, यह इसअजगर भाषा प्रश्न: वस्तु की विशेषताओं() समारोह बनाम

>>> a = object() 
>>> a.hhh = 1 

की तरह एक वस्तु उदाहरण के लिए नई विशेषता बनाने के लिए गैर कानूनी है

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'object' object has no attribute 'hhh' 

फेंकता हालांकि, एक समारोह के लिए वस्तु, यह ठीक है।

>>> def f(): 
... return 1 
... 
>>> f.hhh = 1 

इस अंतर के पीछे तर्क क्या है?

+0

+1, मैं के बारे में अभी था एक ही सवाल पूछने के लिए, लेकिन फिर पहले एक मौजूदा खोज के लिए याद किया! नीचे भी अच्छे जवाब। – Edmund

+0

बहुत अच्छा सवाल है, मुझे एक ही समस्या है –

+0

संभावित डुप्लिकेट [ऑब्जेक्ट क्लास के गुण सेट नहीं कर सकता] [http://stackoverflow.com/questions/1529002/cant-set-attributes-of-object-class) –

उत्तर

22

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

मनमाने ढंग से उदाहरण का समर्थन करने के गुण एक प्रकार एक __dict__ के साथ अपने उदाहरणों में से हर एक की आपूर्ति करनी होगी - कि कार्यों के लिए कोई बड़ी बात नहीं है (जो छोटे वस्तुओं वैसे भी कभी नहीं कर रहे हैं) है, लेकिन यह अच्छी तरह से अन्य वस्तुओं करने के लिए इरादा के लिए हो सकता है छोटा हो। object को प्रकाश के रूप में टाइप करें, और __slots__ को __dict__ से object के उपप्रकारों में से बचने के लिए __slots__ की आपूर्ति करने के लिए, हमने अपनी योग्यता के लिए छोटे, विशेष "मूल्य" प्रकारों का समर्थन किया।

+1

* ऑब्जेक्ट * के अंदरूनी दृश्य के लिए धन्यवाद एलेक्स। मुझे उम्मीद है कि अंतरिक्ष में लाभ प्रयास के लायक था। मुझे अभी भी यह काउंटर-अंतर्ज्ञानी लगता है कि (ए) ऑब्जेक्ट सिस्टम का बेस क्लास ओओ - उदाहरण विशेषताओं की मूलभूत सुविधाओं में से एक का समर्थन नहीं करता है; और (बी) यह सुविधा अचानक किसी भी गैर-सनसनीखेज व्युत्पन्न वर्ग * कक्षा फू (ऑब्जेक्ट) के साथ अस्तित्व में होती है: पास *, जिसे मैं अक्सर उदाहरण विशेषताओं को प्राप्त करने के लिए अक्सर अधिक से अधिक उपयोग करता हूं। – ThomasH

+2

@ थॉमस, क्या आप भी उतने ही आश्चर्यचकित हैं कि जावा में ऑब्जेक्ट "ओओ की मूलभूत सुविधाओं में से एक का समर्थन नहीं करता है" बिल्कुल वैसे ही? इसके प्रत्यक्ष उदाहरणों में उदाहरण विशेषताएँ नहीं हैं। सी # वही है, मुझे विश्वास है। चूंकि (और यह वास्तव में ओओ की मूलभूत विशेषता है: लिस्कोव के सिद्धांत!) कोई उप-वर्ग सुपरक्लास में कुछ ऐसा नहीं ले सकता है, जो आपके अंतर्ज्ञान को पूरा करने के लिए वास्तव में अनंत स्मृति खर्च करेगा: एक ताना के बाद __dict ___.. होना चाहिए और वह निर्देश निश्चित रूप से अपने स्वयं के __dict __.. होना चाहिए और यह कभी नहीं रोक सकता है, कभी नहीं रोक सकता है। आपका अंतर्ज्ञान आपको भ्रमित कर रहा है * एक बहुत *! -) –

+1

@ एलेक्स ठीक है, मैं आपको सुनता हूं। लेकिन शायद यह संभव होगा यदि \ _ \ _ dict \ _ \ _ दुबला ऑब्जेक्ट्स आलसी थे ?! मैं वास्तव में थोड़ा सा विशेषता के साथ एक * ऑब्जेक्ट * उदाहरण के \ _ \ _ dict \ _ \ _ के \ _ \ _ dict \ _ \ _ को एनोटेट करना चाहता हूं, और यह मेरे लिए बिल्कुल पर्याप्त होगा यदि यह \ _ \ _dict \ _ \ _ केवल अस्तित्व में वसंत होगा जब मैं इसे पहले निर्दिष्ट करता हूं। यह कैसा है? – ThomasH

7

एलेक्स मार्टेलि ने आपके प्रश्न का एक शानदार जवाब पोस्ट किया। जो कोई एक अच्छा तरीका की तलाश में है किसी रिक्त ऑब्जेक्ट मनमाना विशेषताओं को पूरा करने के लिए, इस कार्य करें:

class myobject(object): 
    pass 

o = myobject() 
o.anything = 123 

या अधिक कुशल (और बेहतर प्रलेखित) यदि आप विशेषताओं पता:

class myobject(object): 
    __slots__ = ('anything', 'anythingelse') 

o = myobject() 
o.anything = 123 
o.anythingelse = 456 
+0

क्या आप वाकई काम करते हैं कि पहला तरीका काम करता है? मैंने कोशिश की है और मुझे नहीं लगता कि यह काम करता है। –

1

तर्क यह है कि object() का एक उदाहरण एक अपमानजनक विशेष मामला है। यह एक वस्तु है "लेकिन यह स्वयं द्वारा उपयोगी होने के लिए डिज़ाइन नहीं किया गया है।

अस्थायी हैक के रूप में object के बारे में सोचें, पुरानी शैली के प्रकार और कक्षाओं को ब्रिजिंग करें। अजगर 3.0 में यह गुमनामी में है क्योंकि यह अब

class Foo(object): 
    pass 

f = Foo() 
f.randomAttribute = 3.1415926 
+0

ऑब्जेक्ट का मुख्य वास्तविक उपयोग idiom 'sentinel = object()' में है। उद्देश्य के लिए नए वर्ग बनाने के बजाय हाथ में निर्मित "ऑब्जेक्टविड्डेक्ट" रखने के लिए यह मामूली रूप से आसान होगा ;-)। –

+0

objectwithadict - अनिवार्य रूप से 'वर्ग ऑब्जेक्टविथैडिक्ट (ऑब्जेक्ट): पास'? –

0

के हिस्से के रूप में इस्तेमाल किया जाएगा फीका करना होगा यहाँ एक और विकल्प है, के रूप में कम के रूप में मैं यह कर सकता है:

>>> dummy = type('',(), {})() 
>>> dummy.foo = 5 
>>> dummy.foo 
5 
संबंधित मुद्दे