2010-09-15 17 views
6

Hücre adı verilen bir sınıfım var:Özel Python sınıflarında varsayılan yöntemleri geçersiz kılmanın kolay yolu?

class Cell: 

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

    # and other methods... 

Cell._value bir dize, tamsayı vb. (bu nesneyi ne kullanırsam kullanırım) depolar. Xzx54

>>> 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. 

: <Cell object>._value

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. 

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. 

ama daha kolay bir yolu var mı?

+1

Bir tam sayı, 'self._value', bir anahtarla dizine ekleme becerisine sahip midir? Ve hiç bir tamsayı uzunluğunu almayı denediniz mi? Ayrıca, bu muhtemelen cocmmunity wiki olmamalı: Kimse bu şekilde cevap vermek için puan alamıyor ve bize buradaki bazı noktaları seviyoruz. – aaronasterling

+2

-1: Bu bir wiki olmamalı. –

+0

@AaronMcSmooth 'self._value' herhangi bir veri türünü tutabilir, böylece tüm olası yöntemleri kullanmak istiyorum. –

cevap

11

Seni doğru anlıyorsam, bir nesnenin yöntemini bu nesnenin bir özelliğine devretmenin kolay bir yolunu mu arıyorsunuz?

Bir dekoratör tanımlayarak tekrarlılığı bazı önleyebilirsiniz:

@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" 

Muhtemelen tarafından daha da basitleştirmek olabilir:

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 

Daha sonra delege istediğiniz her yöntem için dekoratör uygulayabilirsiniz argümanı olarak çoklu yöntem isimlerini almak için dekoratörün değiştirilmesi.

Sınıfınızın tam bir sarıcı görevi görmesini istiyorsanız, başarısız olan nesneyi denetlemeden önce sınıfın __getattr__ yöntemini geçersiz kılabilirsiniz. Bu, asıl miras olmadan alt sınıfların davranışını taklit ederdi.

+0

"__getattr__" öğesini geçersiz kıldığımı, aradığım şeye daha yakın düşünüyorum ama dekoratör seçeneğindeki değeri de görüyorum. Şimdi sadece "__getattr__" ve "__getattribute__" arasındaki farkı anlamalıyım: http://docs.python.org/reference/datamodel.html#object.__getattribute__ –

0

İstediğiniz c1 + c2 davranışını almak için __add__ yöntemini aşırı yüklemeniz gerekir.

Hepsinin ne olduğuna dair bilgi için here adresine bakın.

İlgili konular