在自定义Python类中覆盖默认方法的简单方法? [英] Easy way of overriding default methods in custom Python classes?
问题描述
我有一个名为Cell的类:
class Cell:
def __init __(self,值,颜色,大小):
self._value = value
self._color = color
self._size = size
#和其他方法...
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']
#等
我可以覆盖所有默认方法:
class Cell:
pre>
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)
#等
...但是有更简单的方法吗?
解决方案如果我正确理解你,你正在寻找一个简单的方法来将一个对象的方法委托给该对象的属性。
你可以避免一些重复性定义装饰器:
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
然后,您可以为每个要委托的方法应用装饰器: p>
@delegate('__ len__','_content')
pre>
@delegate('__ getitem__','_content')
class MyList(object):
def __init __(self,content):
self._content = content
spam = MyList([1,2,3,4, 5])
len(spam)#prints5
spam [0]#prints1
您可以通过修改装饰器以将多个方法名作为参数来进一步简化。
你希望你的类作为一个完整的包装,你可以重写类的
__ getattr __
方法在失败前检查包装的对象。这将模仿没有实际继承的子类的行为。I have a class called Cell:
class Cell: def __init__(self, value, color, size): self._value = value self._color = color self._size = size # and other methods...
Cell._value
will store a string, integer, etc. (whatever I am using that object for). I want all default methods that would normally use the "value" of an object to use<Cell object>._value
so that I can do:>>> 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.
I could override all the default methods:
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.
...but is there an easier way?
解决方案If I understand you correctly, you're looking for an easy way to delegate an object's method to a property of that object?
You can avoid some of the repetitiveness by defining a decorator:
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
You can then apply the decorator for each method you want delegated:
@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"
You could probably simplify it further by modifying the decorator to take multiple method names as argument.
If you want your class to act as a full wrapper, you could probably override the class's
__getattr__
method to check the wrapped object before failing. That would emulate the behaviour of subclasses without actual inheritance.这篇关于在自定义Python类中覆盖默认方法的简单方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!