2012-05-25 6 views
9

मैं एक डेटा संरचना बनाना चाहता हूं जो एक अतिरिक्त कार्यक्षमता के साथ एक शब्दकोश की तरह व्यवहार करता है जो कि किस कुंजी को "उपभोग" किया गया है, इसका ट्रैक रखना है। कृपया ध्यान दें कि मैं केवल मूल्यों को पॉप नहीं कर सकता क्योंकि उनका पुन: उपयोग किया जा रहा है।पाइथन शब्दकोश कुंजी की स्मृति के साथ जो उपयोग किया गया था?

संरचना इन तीन मामलों का समर्थन करना चाहिए, यानी जब तक पहुँचा के रूप में सेवन किया कुंजी के रूप में चिह्नित:

class DictWithMemory(dict): 

    def __init__(self, *args, **kwargs): 
     self.memory = set() 
     return super(DictWithMemory, self).__init__(*args, **kwargs) 

    def __getitem__(self, key): 
     self.memory.add(key) 
     return super(DictWithMemory, self).__getitem__(key) 

    def __contains__(self, key): 
     self.memory.add(key) 
     return super(DictWithMemory, self).__contains__(key) 

    def get(self, key, d=None): 
     self.memory.add(key) 
     return super(DictWithMemory, self).get(key, d) 

    def unused_keys(self): 
     """ 
     Returns the list of unused keys. 
     """ 
     return set(self.keys()).difference(self.memory) 

जैसा कि मैंने साथ बहुत परिचित नहीं हूँ:

if key in d: 
    ... 
d[key] 
d.get(key) 

यह मैं क्या लिखा है है dict के आंतरिक, क्या इस परिणाम को प्राप्त करने का एक बेहतर तरीका है?

+1

कितनी बार प्रयोग करते हैं 'unused_keys()' ? यदि आपने इस सेट से चाबियाँ निकालने का प्रयास करने के लिए सेट और गेटटर को चाबियाँ जोड़ने के लिए सेटर को सजाया है, तो यह बेहतर परफॉर्मेंस हो सकता है - ** सुंदरता ** भाग के बारे में निश्चित नहीं है, सोचा – Aprillion

+2

इसके अलावा: 'unused_keys' को वापस क्यों करना चाहिए सूची? इसमें कोई आंतरिक आदेश नहीं है, इसलिए यह एक सेट वापस करने के लिए समझ में आता है। –

+0

@ थॉमस के: समरूपता के लिए, 'कुंजी' एक सूची लौट रहा है। – badzil

उत्तर

4

यहां एक समाधान है जो मेटाक्लास के अंदर सबकुछ दूर करता है। मुझे यकीन है कि अगर यह वास्तव में किसी भी अधिक सुरुचिपूर्ण है नहीं कर रहा हूँ, लेकिन यह आप कैसे इस्तेमाल किया कुंजी स्टोर करने के लिए के बारे में अपना मन बदल चाहिए कैप्सूलीकरण की कुछ राशि प्रदान करता है:

class KeyRememberer(type): 

    def __new__(meta, classname, bases, classDict): 
     cls = type.__new__(meta, classname, bases, classDict) 

     # Define init that creates the set of remembered keys 
     def __init__(self, *args, **kwargs): 
      self.memory = set() 
      return super(cls, self).__init__(*args, **kwargs) 
     cls.__init__ = __init__ 

     # Decorator that stores a requested key in the cache 
     def remember(f): 
      def _(self, key, *args, **kwargs): 
       self.memory.add(key) 
       return f(self, key, *args, **kwargs) 
      return _ 

     # Apply the decorator to each of the default implementations 
     for method_name in [ '__getitem__', '__contains__', 'get' ]: 
      m = getattr(cls, method_name) 
      setattr(cls, method_name, remember(m)) 

     return cls 


class DictWithMemory(dict): 

    # A metaclass that ensures the object 
    # has a set called 'memory' as an attribute, 
    # which is updated on each call to __getitem__, 
    # __contains__, or get. 
    __metaclass__ = KeyRememberer 

    def unused_keys(self): 
     """ 
     Returns the list of unused keys. 
     """ 
     print "Used", self.memory 
     return list(set(super(DictWithMemory, 
           self).keys()).difference(self.memory)) 
+1

मुझे आपके मेटाक्लास के उपयोग को सीमित करने के लिए पसंद है जो गतिशील कॉन्फ़िगरेशन को "उपभोक्ताओं" के रूप में माना जाता है। – badzil

+0

मैं @ बैडिल की टिप्पणी से सहमत हूं और सोचता हूं कि इसे और भी आगे जाना चाहिए और अपने ग्राहकों को परिभाषित करने या ओवरराइड करने की इजाजत देनी चाहिए कि कौन सी विधियों को उपभोक्ताओं माना जाता है - सुविधा पर मुझे विश्वास है कि आसानी से जोड़ा जा सकता है। – martineau

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