2009-08-06 8 views
5

निम्नलिखित वर्ग पर विचार करें:एक अजगर की क्लास के लिए गेटर और सेटर को नियंत्रित करना

class Token: 
    def __init__(self): 
     self.d_dict = {} 

    def __setattr__(self, s_name, value): 
     self.d_dict[s_name] = value 

    def __getattr__(self, s_name): 
     if s_name in self.d_dict.keys(): 
      return self.d_dict[s_name] 
     else: 
      raise AttributeError('No attribute {0} found !'.format(s_name)) 

मेरी कोड टोकन में कुछ अन्य कार्य हो (get_all की तरह() जो वापसी d_dict, है (s_name) जो मुझे बताओ अगर मेरे टोकन एक विशेष विशेषता है)।

वैसे भी, मुझे लगता है कि यह मेरी योजना में एक दोष है क्योंकि यह काम नहीं करता है: जब मैं एक नया उदाहरण बनाता हूं, तो पाइथन __setattr__('d_dict', '{}') पर कॉल करने का प्रयास करता है।

मैं टोकन.सेट (नाम, मूल्य) जैसे कुछ लिखने के बिना एक समान व्यवहार (शायद एक और पाइथोनिक तरीके से कैसे प्राप्त कर सकता हूं) प्राप्त कर सकता हूं और प्रत्येक नाम को सेट (नाम) प्राप्त कर सकता हूं या एक विशेषता प्राप्त कर सकता हूं टोकन।

डिजाइन दोष और/या मूर्खता के बारे में आलोचकों :) का स्वागत करते हैं

धन्यवाद!

उत्तर

3

आपको विशेष-मामले d_dict की आवश्यकता है।

हालांकि, उपर्युक्त कोड में, आप जो कुछ भी करते हैं, वह दोहराता है कि __dict__ के साथ कोई वस्तु क्या है, इसलिए यह काफी व्यर्थ है। क्या आप सही ढंग से अनुमान लगाते हैं यदि आप विशेष मामले के लिए कुछ विशेषताओं का इरादा रखते हैं और उन लोगों के लिए व्यावहारिक रूप से तरीकों का उपयोग करते हैं?

उस स्थिति में, आप गुणों का उपयोग कर सकते हैं।

class C(object): 
    def __init__(self): 
     self._x = None 

    @property 
    def x(self): 
     """I'm the 'x' property.""" 
     return self._x 

    @x.setter 
    def x(self, value): 
     self._x = value 

    @x.deleter 
    def x(self): 
     del self._x 
1

एक समाधान, बहुत पाइथनिक नहीं बल्कि काम करता है। जैसा कि लेनार्ट रीगेब्रो ने इंगित किया है, आपको d_dict के लिए एक विशेष मामला उपयोग करना होगा।

class Token(object): 

    def __init__(self): 
     super(Token,self).__setattr__('d_dict', {}) 

    def __getattr__(self,name): 
     return self.a[name] 

    def __setattr__(self,name,value): 
     self.a[name] = value 

आपको नई शैली कक्षाओं का उपयोग करने की आवश्यकता है।

1

यह याद रखना उचित है कि __getattr__ केवल कॉल किया जाता है यदि विशेषता वस्तु में मौजूद नहीं है, जबकि __setattr__ हमेशा कॉल किया जाता है।

3

इस तरह __dict__ कार्यों की विशेष आवरण:

def __init__(self): 
    self.__dict__['d_dict'] = {} 

कि के लिए एक नई शैली वर्ग का उपयोग करने की जरूरत नहीं है।

+0

मुझे लगता है कि मैं ऐसा करूँगा :) वैसे भी, मैं पायथन 3.1 का उपयोग करता हूं, इसलिए मेरी सभी कक्षाएं नई स्टाइल क्लास हैं। myClassInstance.name1 = मान 1 myClassInstance.name2 2 = मान उचित साथ : – thomas

2

समस्या __init__ विधि में आपके कोड के मूल्यांकन के समय में प्रतीत होती है। आप __new__ विधि को परिभाषित कर सकते हैं और __init__ के बजाय वहां d_dict चर प्रारंभ कर सकते हैं। थोड़ा सा हैकिश है लेकिन यह काम करता है, याद रखें कि कुछ महीनों के बाद यह टिप्पणी करने के लिए याद रखें, यह कुल जादू होगा।

>>> class Foo(object): 
...  def __new__(cls, *args): 
...    my_cls = super(Foo, cls).__new__(cls, *args) 
...    my_cls.d_dict = {} 
...    return my_cls 

>>> f = Foo() 
>>> id(f.d_dict) 
3077948796L 
>>> d = Foo() 
>>> id(d.d_dict) 
3078142804L 

स्पष्टीकरण का वचन कारण है कि मैं विचार है कि hackish: रिटर्न वर्ग का नया उदाहरण __new__ करने के लिए कॉल तो फिर d_dict में initialised वहाँ स्थिर की तरह है, लेकिन यह शब्दकोश प्रत्येक का नया उदाहरण के साथ initialised है समय वर्ग "बनाया गया" इसलिए सबकुछ आपकी इच्छानुसार काम करता है।

0

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

# This is a class that serves as a dictionary but also has user-defined methods 
class mydict(dict): pass 

# This is a class that allows setting x.attr = value or getting x.attr: 
class mysetget: pass 

# This is a class that allows setting x.attr = value or getting x.attr: 
class mygetsethas: 
    def has(self, key): 
     return key in self.__dict__ 

x = mygetsethas() 
x.a = 5 
print(x.has('a'), x.a) 

मुझे लगता है कि पिछले वर्ग आप क्या मतलब के सबसे करीब है, और मैं भी वाक्य रचना के साथ खेलते हैं और इसे से खुशी की बहुत सारी प्राप्त करना चाहते, लेकिन दुर्भाग्य से यह एक अच्छी बात नहीं है। शब्दकोशों को फिर से कार्यान्वित करने के लिए ऑब्जेक्ट विशेषताओं का उपयोग करने की सलाह क्यों नहीं दी जाती है: आप x.3 का उपयोग नहीं कर सकते हैं, आप x.has() के साथ संघर्ष करते हैं, आपको has('a') और कई अन्य में उद्धरण देना होगा।

+0

मेरा लक्ष्य एक कंटेनर है कि मुझे यह किसी भी मनमाने ढंग से विशेषता देने की अनुमति (मैं पहले से नहीं है कि कितने और न ही उनके नाम), उदाहरण के लिए प्रदान करना है कॉल करें, मैं एक ऐसे शब्दकोष को पुनर्प्राप्त करना चाहता हूं जिसमें मेरे गुणों का नाम और मान निम्न फ़ॉर्म के अंतर्गत होगा: {'name1': value1, 'name2': value2} वैल्यूएक्स कोई अजगर या कस्टम प्रकार हो सकता है। – thomas

+0

फिर आपका सबसे अच्छा सर्वश्रेष्ठ दूसरा वर्ग है, 'क्लास मायसेटेट: पास'। आप गुण सेट करने में सक्षम होंगे और फिर उन्हें 'x .__ dict__'' से पुनर्प्राप्त कर पाएंगे। –

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