2011-04-22 5 views
14

मेरे पास सैकड़ों हजारों नोड्स के साथ एक बड़ा पेड़ है, और मैं स्मृति खपत को कम करने के लिए __slots__ का उपयोग कर रहा हूं। मुझे बस एक बहुत ही अजीब बग मिली और इसे ठीक कर दिया, लेकिन मैंने जो व्यवहार देखा वह मुझे समझ में नहीं आया।पायथन, __slots__, विरासत, और वर्ग चर ==> विशेषता केवल पढ़ने के लिए बग

>>> node = NodeTypeA("Monty") 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 4, in __init__ 
AttributeError: 'NodeTypeA' object attribute 'name' is read-only 

कोई त्रुटि है, तो NodeTypeA.name परिभाषित नहीं है (ओर टिप्पणी नहीं है:

class NodeBase(object): 
    __slots__ = ["name"] 
    def __init__(self, name): 
     self.name = name 

class NodeTypeA(NodeBase): 
    name = "Brian" 
    __slots__ = ["foo"] 

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

यहाँ एक सरलीकृत कोड नमूना है कि विशेषता वहां गलती से किया गया था, और वहां होने का कोई कारण नहीं था)। वहाँ भी कोई त्रुटि है, तो NodeTypeA.__slots__ परिभाषित नहीं किया जाता है, और यह इसलिए एक __dict__ है।

बात मुझे समझ नहीं आता है: क्यों एक सुपर क्लास में एक वर्ग चर के अस्तित्व बच्चे कक्षा में एक स्लॉट में एक उदाहरण चर की स्थापना के साथ हस्तक्षेप करता है?

किसी को क्यों इस संयोजन object attribute is read-only त्रुटि में परिणाम व्याख्या कर सकते हैं? मुझे पता है कि मेरा उदाहरण बढ़ गया है, और वास्तविक कार्यक्रम में जानबूझकर होने की संभावना नहीं है, लेकिन यह इस व्यवहार को कम अजीब नहीं बनाता है।

धन्यवाद,
जोनाथन

+0

'NodeTypeA' एक वर्ग चर' name' पैदा कर रही है और उदाहरण चर 'NodeBase' में परिभाषित करने के लिए एक मूल्य बताए नहीं। क्या यह जानबूझकर है? – unholysampler

+0

यह पहली बार जानबूझकर नहीं था - मुझे गलती से यह मेरे कोड में था, जिसके कारण मैं बग पूछ रहा था। लेकिन फिर मुझे उत्सुकता है कि कोड ऐसा क्यों व्यवहार करता है, इसलिए मैं जानबूझकर इसे अपने कोड नमूने में डालता हूं। – Jonathan

उत्तर

17

एक छोटे उदाहरण:

class C(object): 
    __slots__ = ('x',) 
    x = 0 

C().x = 1 

documentation on slots राज्यों एक बिंदु पर:

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

मुझे लगता है कि इसका मतलब है कार्यान्वयन वर्ग चर इस समस्या को रोकने के लिए केवल पढ़ने के लिए वर्णनकर्ता में __slots__ में इस्तेमाल एक नाम है कि हो जाएगा।

+1

ऐसा ही एक सवाल का जवाब भी यहाँ पोस्ट किया जाता है: http://stackoverflow.com/questions/820671/python-slots-and-attribute-is-read-only – Santa

+0

अच्छा बिंदु। मुझे एहसास नहीं हुआ कि यह उस के लिए सरलीकृत है - मैंने सोचा था कि विरासत समस्या का हिस्सा था। जाहिर है, जैसा कि @ सांता बताता है, यह वही प्रश्न जैसा ही है। – Jonathan

+0

पायथन यहां केवल पढ़ने योग्य वर्णनकर्ता नहीं बनाते हैं। क्या होता है कि उदाहरण के एक '__dict__' नहीं है, और' नाम = "ब्रायन" 'में स्ट्रिंग' 'NodeTypeA' NodeBase' में' name' स्लॉट के लिए बनाई गई स्लॉट वर्णनकर्ता छुपाता है।पायथन देखता है कि उदाहरण में 'नाम' विशेषता है (क्योंकि विशेषता लुकअप '" ब्रायन "स्ट्रिंग पाता है, लेकिन विशेषता असाइन करने योग्य नहीं है (क्योंकि" ब्रायन "' '__set__' विधि नहीं है और उदाहरण में '__dict__' नहीं है), इसलिए यह रिपोर्ट करता है कि विशेषता केवल पढ़ने के लिए है। – user2357112

-1
class NodeBase(object): 
__slots__ = ["name"] 
def __init__(self, name): 
    self.name = name 

class NodeTypeA(NodeBase): 
    super().name = "Brian" 
    __slots__ = ["foo"] 

सुपर()

+1

हाय @ टोनी-डायना, एसओ में आपका स्वागत है। जितना संभव हो उतना समझाएं, आपका जवाब। –

+0

कृपया यह कोड बताएं कि यह कोड क्या करता है और यह प्रश्न का उत्तर कैसे देता है। –

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