2010-09-15 56 views
6

我有一个类叫做细胞:在自定义Python类中覆盖默认方法的简单方法?

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'有能力被一个键索引?你有没有尝试过一个整数的长度?另外,这可能不应该是cocmmunity wiki:没有人会以这种方式回答问题,我们在这里爱我们的一些观点。 – aaronasterling 2010-09-15 18:48:58

+2

-1:这不应该是一个维基。 – 2010-09-15 18:49:18

+0

@AaronMcSmooth'self._value'可以容纳任何数据类型,所以我想拥有所有可能的方法。 – 2010-09-16 12:41:40

回答

11

如果我正确理解你,你正在寻找一种简单的方法将对象的方法委托给该对象的属性?

您可以通过定义一个装饰避免一些重复性:

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 

您可以再申请装饰为每个要委托的方法:

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

你也许可以通过进一步简化它修改装饰器以将多个方法名称作为参数。

如果你想让你的类充当一个完整的包装器,你可能会重写该类的__getattr__方法来检查包装的对象之前失败。这将模仿没有实际继承的子类的行为。

+0

我认为重写'__getattr__'更接近我所寻找的,但我也看到了装饰器选项中的值。现在我只需要理解'__getattr__'和'__getattribute__'之间的区别:http://docs.python.org/reference/datamodel.html#object.__getattribute__ – 2010-09-16 13:28:15

0

您需要重载__add__方法才能获得所需的c1 + c2行为。

请参阅here了解它们的含义。