2009-08-16 16 views
53

(अजगर खोल में लिखित)आप पाइथन में ऑब्जेक्ट्स में विशेषता क्यों नहीं जोड़ सकते?

>>> o = object() 
>>> o.test = 1 

Traceback (most recent call last): 
    File "<pyshell#45>", line 1, in <module> 
    o.test = 1 
AttributeError: 'object' object has no attribute 'test' 
>>> class test1: 
    pass 

>>> t = test1() 
>>> t.test 

Traceback (most recent call last): 
    File "<pyshell#50>", line 1, in <module> 
    t.test 
AttributeError: test1 instance has no attribute 'test' 
>>> t.test = 1 
>>> t.test 
1 
>>> class test2(object): 
    pass 

>>> t = test2() 
>>> t.test = 1 
>>> t.test 
1 
>>> 

आप इसे करने के गुण को जोड़ने की अनुमति क्यों आपत्ति नहीं करता है?

उत्तर

38

सूचना है कि एक object उदाहरण नहीं __dict__ विशेषता है: slots पर

>>> class Foo(object): 
...  __slots__ = {} 
... 
>>> f = Foo() 
>>> f.bar = 42 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'Foo' object has no attribute 'bar' 

डॉक्स से हवाला देते हुए:

>>> dir(object()) 
['__class__', '__delattr__', '__doc__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__'] 

एक उदाहरण एक व्युत्पन्न वर्ग में इस व्यवहार को वर्णन करने के लिए

[...] __slots__ घोषणा लेना उदाहरण चर के अनुक्रम और प्रत्येक चर के लिए एक मान रखने के लिए प्रत्येक उदाहरण में पर्याप्त जगह सुरक्षित है। अंतरिक्ष सहेजा गया है क्योंकि प्रत्येक उदाहरण के लिए __dict__ नहीं बनाया गया है।

संपादित करें: टिप्पणियों से ThomasH उत्तर देने के लिए, ओपी के परीक्षण वर्ग एक "पुरानी शैली" वर्ग है। प्रयास करें:

>>> class test: pass 
... 
>>> getattr(test(), '__dict__') 
{} 
>>> getattr(object(), '__dict__') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'object' object has no attribute '__dict__' 

और आप ध्यान देंगे एक __dict__ उदाहरण है। ऑब्जेक्ट क्लास में __slots__ परिभाषित नहीं हो सकता है, लेकिन परिणाम समान है: __dict__ की कमी, जो एक विशेषता के गतिशील असाइनमेंट को रोकती है। मैंने यह स्पष्ट करने के लिए अपना जवाब पुनर्गठित किया है (दूसरे अनुच्छेद को शीर्ष पर ले जाएं)।

+2

तो, आप कह रहे हैं कि * ऑब्जेक्ट * वर्ग उदाहरण सदस्यों के असाइनमेंट को रोकने के लिए \ _ \ _ स्लॉट \ _ \ _ को एक तरफ या किसी अन्य तरीके से उपयोग कर रहा है। क्या यह एक धारणा या तथ्य है (यानी यह * ऑब्जेक्ट * के कार्यान्वयन में है)? क्योंकि * ऑब्जेक्ट * इंस्टेंस से \ _ \ dict \ _ \ _ की केवल अनुपस्थिति संकेतक नहीं है। ओपी के * test1 * वर्ग के उदाहरण एक ही गायब \ _ \ _ dict \ _ \ _ दिखाते हैं जब dir() के साथ बुलाया जाता है, लेकिन फिर भी इंस्टेंस सदस्यों के असाइनमेंट की अनुमति देता है। – ThomasH

+1

@ थॉमस एच, कृपया उत्तर में जो नोट मैंने जोड़ा है उसे देखें। – ars

3

अच्छा सवाल है, मेरा अनुमान है कि इसे इस तथ्य के साथ करना है कि objectअंतर्निहित/एक्सटेंशन प्रकार है।

>>> class test(object): 
... pass 
... 
>>> test.test = 1 
>>> object.test = 1 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: can't set attributes of built-in/extension type 'object' 

IIRC, यह, setattr() उड़ा वस्तु एक __dict__ विशेषता नहीं है जब एक __dict__ विशेषता की उपस्थिति या, और अधिक सही ढंग से से कोई लेना देना नहीं है।

संबंधित मुद्दे