2013-10-24 6 views
5

मैं एक वर्ग जो __slots__ को परिभाषित करता है है कहते हैं:__setattr सकते हैं __() __slots__ के साथ एक कक्षा में परिभाषित किया जा सकता है?

class Foo(object): 
    __slots__ = ['x'] 

    def __init__(self, x=1): 
     self.x = x 

    # will the following work? 
    def __setattr__(self, key, value): 
     if key == 'x': 
      object.__setattr__(self, name, -value) # Haha - let's set to minus x 

मैं इसके लिए __setattr__() को परिभाषित कर सकते हैं?

Foo के बाद __dict__ नहीं है, यह क्या अपडेट करेगा?

उत्तर

9

आपके सभी कोड, मूल्य को अस्वीकार करने के अलावा, माता-पिता वर्ग __setattr__ पर कॉल करते हैं, जो आपके __setattr__ विधि के बिना बिल्कुल होगा। तो संक्षिप्त जवाब यह है: निश्चित रूप से आप __setattr__ को परिभाषित कर सकते हैं।

आप ऐसा नहीं कर सकते क्या नहीं एक __dict__ विशेषता है, __setattr__ को फिर से परिभाषित self.__dict__ उपयोग करने के लिए है, क्योंकि स्लॉट के साथ एक वर्ग के उदाहरण है। लेकिन ऐसे मामलों करना एक self.x विशेषता यह सामग्री सिर्फ उदाहरण पर एक शब्दकोश में संग्रहीत नहीं कर रहे हैं है।

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

तो, एक __setattr__ हुक में, आप सिर्फ उन वर्णनकर्ता के बजाय सीधे कॉल कर सकते हैं:

def __setattr__(self, key, value): 
    if key == 'x': 
     Foo.__dict__[key].__set__(self, -value) 

दिलचस्प चक्कर: एक __slots__ विशेषता के बिना हाँ, वर्गों पर, वहाँ की जानकारी देता है कि आप पहुँच देना होगा है

>>> class Bar(object): pass 
... 
>>> Bar.__dict__['__dict__'] 
<attribute '__dict__' of 'Bar' objects> 
>>> Bar.__dict__['__dict__'].__get__(Bar(), Bar) 
{} 

जो सामान्य उदाहरणों दिखाई दे सकते हैं: उदाहरणों में से __dict__ वस्तु को ऊपर self.__dict__। जो आपको आश्चर्यचकित करता है कि Bar.__dict__ ऑब्जेक्ट कहां पाया जाता है। अजगर में, यह है turtles all the way down, आप देखो चाहते हैं कि निश्चित रूप से type वस्तु पर आपत्ति:

>>> type.__dict__['__dict__'] 
<attribute '__dict__' of 'type' objects> 
>>> type.__dict__['__dict__'].__get__(Bar, type) 
dict_proxy({'__dict__': <attribute '__dict__' of 'Bar' objects>, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'Bar' objects>, '__doc__': None}) 
+0

__dict__ यहाँ काम करता है? ऐसा इसलिए है क्योंकि __dict__ और ढेर वस्तुओं का प्रभावी पता वही है, और यह एक ईस्टर अंडे है? या आप __slots__ मतलब था? –

+0

@CorleyBrigman: ** वर्ग के '__dict__' भ्रमित न करें ** ** उदाहरण के साथ **। कक्षा 'फू' के उदाहरणों में '__dict__' विशेषता नहीं है। –

+0

@ कोर्लेब्रिगमैन: और 'फू' उदाहरणों में '__dict__' विशेषता नहीं है, क्योंकि' Foo .__ dict __ ['__ dict __'] '' keyError 'उठाती है। –

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

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