2010-09-15 6 views
6

मेरे पास सेल नामक एक वर्ग है:कस्टम पायथन कक्षाओं में डिफ़ॉल्ट तरीकों को ओवरराइड करने का आसान तरीका?

class Cell: 

    def __init__(self, value, color, size): 
     self._value = value 
     self._color = color 
     self._size = size 

    # and other methods... 

Cell._value एक स्ट्रिंग, पूर्णांक, आदि संग्रहीत करेगा (जो भी मैं उस ऑब्जेक्ट का उपयोग कर रहा हूं)। मैं सभी डिफ़ॉल्ट विधियों को चाहता हूं जो आमतौर पर <Cell object>._value का उपयोग करने के लिए किसी ऑब्जेक्ट के "मान" का उपयोग करें ताकि मैं कर सकूं:

>>> c1 = Cell(7, "blue", (5,10)) 
>>> c2 = Cell(8, "red", (10, 12)) 
>>> print c1 + c2 
15 

>>> c3 = Cell(["ab", "cd"], "yellow", (50, 50)) 
>>> print len(c3), c3 
2 ['ab', 'cd'] 

# etc. 

मैं सभी डिफ़ॉल्ट विधियों को ओवरराइड कर सकता हूं:

class Cell: 

    def __init__(self, value, color, size): 
     # ... 

    def __repr__(self): 
     return repr(self._value) 

    def __str__(self): 
     return str(self._value) 

    def __getitem__(self, key): 
     return self._value[key] 

    def __len__(self): 
     return len(self._value) 

    # etc. 

... लेकिन क्या कोई आसान तरीका है?

+1

एक पूर्णांक, 'self._value' क्यों एक कुंजी द्वारा अनुक्रमित करने की क्षमता है? और क्या आपने कभी एक पूर्णांक की लंबाई लेने की कोशिश की है? इसके अलावा, यह संभवतः कॉकम्यूनिटी विकी नहीं होना चाहिए: किसी को भी इस तरह का जवाब देने के लिए अंक नहीं मिलते हैं और हम यहां कुछ बिंदुओं से हमें प्यार करते हैं। – aaronasterling

+2

-1: यह विकी नहीं होना चाहिए। –

+0

@AaronMcSmooth 'self._value' किसी भी डेटा प्रकार को पकड़ सकता है इसलिए मैं सभी संभावित विधियों को उपलब्ध करना चाहता हूं। –

उत्तर

11

यदि मैं आपको सही ढंग से समझता हूं, तो आप उस ऑब्जेक्ट की किसी संपत्ति के ऑब्जेक्ट की विधि को प्रतिनिधि करने का एक आसान तरीका ढूंढ रहे हैं?

आप एक डेकोरेटर को परिभाषित करते हुए repetitiveness के कुछ से बचने कर सकते हैं:

@delegate('__len__', '_content') 
@delegate('__getitem__', '_content') 
class MyList(object): 
    def __init__(self, content): 
     self._content = content 

spam = MyList([1,2,3,4,5]) 

len(spam) # prints "5" 

spam[0] # prints "1" 

आप शायद इसे आगे से आसान बनाने में कर सकते हैं:

def delegate(method, prop): 
    def decorate(cls): 
     setattr(cls, method, 
      lambda self, *args, **kwargs: 
       getattr(getattr(self, prop), method)(*args, **kwargs)) 
     return cls 
    return decorate 

फिर आप प्रत्येक विधि आप प्रत्यायोजित चाहते हैं के लिए आवेदन कर सकते हैं डेकोरेटर कई विधि नाम तर्क के रूप में लेने के लिए सजावटी को संशोधित करना।

यदि आप अपनी कक्षा को एक पूर्ण रैपर के रूप में कार्य करना चाहते हैं, तो संभवतः आप असफल होने से पहले लिपटे ऑब्जेक्ट को जांचने के लिए कक्षा की __getattr__ विधि को ओवरराइड कर सकते हैं। यह वास्तविक विरासत के बिना उप-वर्गों के व्यवहार का अनुकरण करेगा।

+0

मुझे लगता है कि '__getattr__' ओवरराइडिंग जो मैं ढूंढ रहा हूं उसके करीब है लेकिन मुझे सजावटी विकल्प में भी मूल्य दिखाई देता है। अब मुझे '__getattr__' और '__getattribute__' के बीच अलग-अलग समझने की आवश्यकता है: http://docs.python.org/reference/datamodel.html#object.__getattribute__ –

0

आपको c1 + c2 व्यवहार प्राप्त करने के लिए आपको __add__ विधि अधिभारित करने की आवश्यकता है।

here देखें कि वे सभी क्या हैं।

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