1

問題を解決するために継承を伴うオブジェクト指向のアプローチを使用していますが、この問題に「ダックタイピング」の原則を適用する方法を考えています。

( 、および)BoxOfShapesのリストでインスタンス化されるクラスがあります。ShapesCircleSquareRectangle

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たため、新しい種類の形状を考え出すたびに定義を変更する必要があります.

私の質問は、この種のシナリオでダックタイピングを (どのように) 適用するのでしょうか?

4

3 に答える 3

1

継承を効果的に使用する方法はすでに用意されています。type形状ごとにメソッドを定義します。BoxOfShapes実装で型をその型の要素のリストにマップするディクショナリを作成するだけです。

他の人が示唆しているように、組み込みtype()関数を使用してください。形状の名前の文字列表現が必要な場合は、別のインスタンス メソッドを使用します。

于 2013-08-16T21:30:51.670 に答える