我正在使用一种带有继承的面向对象的方法来解决一个问题,我想知道如何将'Duck类型‘原则应用于这个问题。
我有一个类BoxOfShapes,它将使用Shapes列表( Circle、Square和Rectangle)实例化。
import numpy as np
class Shape(object):
def __init__(self,area):
self.area = area;
def dimStr(self):
return 'area: %s' % str(self.area)
def __repr__(self):
return '%s, %s' % (self.__class__.__name__, self.dimStr()) + ';'
class Circle(Shape):
def __init__(self,radius):
self.radius = radius
def dimStr(self):
return 'radius %s' % str(self.radius)
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
def dimStr(self):
return '%s x %s' % (str(self.width), str(self.height))
class Square(Rectangle):
def __init__(self, side):
self.width = side
self.height = side
class BoxOfShapes(object):
def __init__(self, elements):
self.elements = elements
def __repr__(self):
pass
listOfShapes = [Rectangle(10,13),Rectangle(9,5),Circle(12),Circle(8),Circle(36),Square(10)]
myBox = BoxOfShapes(listOfShapes)
print myBox因此,让我们看看__repr__()的BoxOfShapes方法。据我所知,鸭子类型的实现可能类似于,
def __repr__(self):
return str(self.elements)因为这说明‘我不在乎我有哪些元素,只要它们实现了__str__()或__repr__()。
>>> print myBox
[Rectangle, 10 x 13;, Rectangle, 9 x 5;, Circle, radius 12;, Circle, radius 8;, Circle, radius 36;, Square, 10 x 10;]假设我想从BoxOfShapes获得更多人类可读的输出--我知道所有的形状都是特定类型的,所以分类比较好,它们是这样的:
def __repr__(self):
circles = [ el.dimStr() for el in self.elements if isinstance(el, Circle)]
squares = [ el.dimStr() for el in self.elements if isinstance(el, Square)]
rectangles = [el.dimStr() for el in self.elements if (isinstance(el, Rectangle) and not isinstance(el, Square)) ]
return 'Box of Shapes; Circles: %s, Squares: %s, Rectangles: %s;' % ( str(circles), str(squares), str(rectangles))它的输出是
>>> print myBox
Box of Shapes; Circles: ['radius 12', 'radius 8', 'radius 36'], Squares: ['10 x 10'], Rectangles: ['10 x 13', '9 x 5'];这很容易读懂,但我不再使用鸭子类型,现在每当我想出一种新的形状时,我就必须改变我对BoxOfShapes的定义。
我的问题是,在这种情况下,如何应用鸭子类型?
发布于 2013-08-16 21:36:46
这实际上不是鸭子类型的问题,而是一般的继承问题(例如,您可以问与Java完全相同的问题,Java没有鸭子类型的概念)。
您想要做的只是创建一个字典映射类型来列出实例。动态地这样做是相当容易的:
from collections import defaultdict
type_dict = defaultdict(list)
for element in self.elements:
type_dict[element.type()].append(element.dimStr())
return ','.join('%s: %s' for k, v in type_dict.items())发布于 2013-08-16 21:30:51
您已经为有效使用继承铺平了道路。为每个形状定义一个type方法。只需创建一个字典,将该类型映射到BoxOfShapes实现中该类型的元素列表。
正如其他人所建议的,使用内置的type()函数。如果需要形状名称的字符串表示形式,请使用单独的实例方法。
发布于 2013-08-16 21:34:31
这是一个解决方案
from collections import defaultdict
class BoxOfShapes(object):
def __init__(self, elements):
self.elements = elements
self.groupings = defaultdict(list)
for element in elements:
self.groupings[type(element)].append(element)
def __repr__(self):
return "Box of Shapes: %s;" % ", ".join(type(group[0]).__name__ + "s: " + str(group) for group in self.groupings.itervalues())不过,这似乎不太理想。
一个更合适的repr可能只是返回len of self.elements。
def __repr__(self):
return "<%s, length=%s>" % (type(self).__name__, len(self.elements))https://stackoverflow.com/questions/18282343
复制相似问题