2017-12-09 8 views
1

Circleクラスは、Pointオブジェクトを中心に使用します。点の代わりにタプルでCircleオブジェクトを作成できるようにするには、from_tupleという@classmethodが必要です。 This is how the output should look like for from_tuple()タプルでオブジェクトを作成できるfrom_tuple()classmethodを追加しますか?

2人のゲッターとセンター用の1組のセッターを持つ乱雑なコードをお詫び申し上げます。その中心がタプルでなければならないことを知って、私は本当に最後まで混乱しました。 from_tuple()にアクセスする際にゲッターのAttributeErrorを解決するのを手伝ってください。

エラーメッセージは以下

>>> center_point=3,4 
>>> circle=Circle.from_tuple(center=center_point) 
>>> circle 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "C:\Users\hole1\Desktop\ProgramIntro\shapes.py", line 54, in __repr__ 
    return "Circle(center=Point({0}, {1}), radius={2})".format(self.center[0],self.center[1],self.radius) 
    File "C:\Users\hole1\Desktop\ProgramIntro\shapes.py", line 65, in center 
    return(self._center) 
AttributeError: 'Circle' object has no attribute '_center' 

下に示されているが、クラスPointである:

import math 
class Point: 
    def __init__(self,x=0,y=0): 
     self.x = x 
     self.y = y 
     self.data=[x,y] 
    def __getitem__(self, index): 
     return self.data[index] 
    def __iter__(self): 
     yield self.x 
     yield self.y 
    def __add__(self,other): 
     return Point(self.x+other.x,self.y+other.y) 
    def __mul__(self,n): 
     return Point(self.x*n,self.y*n) 
    def __rmul__(self,n): 
     return Point(n*self.x,n*self.y) 
    @classmethod 
    def from_tuple (cls, self=(0,0)): 
     return cls(*self) 
    def loc_from_tuple(self,t=(0,0)): 
     self.x=t[0] 
     self.y=t[1] 
    def __str__(self): 
     return "Point at ({0}, {1})".format(self.x,self.y) 
    def __repr__(self): 
     return"Point(x={0}, y={1})".format(self.x,self.y) 

以下クラス円です。

class Circle(Point): 
     def __init__(self, center=(0,0), radius=1): 
      try: 
       x, y = center 
       super(Circle, self).__init__(x,y) 
       Point.__init__(self,center) 
       self.radius=radius 
       self.center=center 
      except (UnboundLocalError, TypeError, AttributeError) as e: 
        pass 
      if not center == (0,0): 
       if not isinstance(center,Point): 
        if not isinstance(center, tuple): 
         raise TypeError("The center must be a oint!") 
     def __str__(self): 
      return "Circle with center at ({0}, {1}) and radius {2}".format(self.center.x, self.center.y, self.radius) 
     def __repr__(self): 
      return "Circle(center=Point({0}, {1}), radius={2})".format(self.center[0],self.center[1],self.radius) 
     @property 
     def center(self): 
      return self.x, self.y 
     @property 
     def center(self): 
      return(self._center) 
     @center.setter 
     def center(self, center): 
      if not center == (0,0): 
       if not isinstance(center,Point): 
        raise TypeError("The center must be a Point!") 
      self._center=center 
     @property 
     def radius(self): 
      return self._radius 
     @radius.setter 
     def radius(self, radius): 
      if radius<0: 
       raise ValueError('The radius cannot be negative') 
      self._radius=radius 
     @classmethod 
     def from_tuple(cls, center=(0,0),radius=1): 
      return cls(center,radius) 
+0

1.どのようにエラーを再現できますか?私は 'Circle = Circle.from_tuple(center = Point(0、0)、radius = 1)'を試してみました。 2.コード/エラーを画像で投稿しないでください:コード/エラーをコピーし、あなたの投稿にテキストとして追加してください。ありがとう – alfasin

+1

'Circle'を継承する' Point'は_quite_デザインの選択 –

+0

混乱して申し訳ありません。投稿を編集して、コードエラーを示す画像を削除しました。うまくいけばそれは明らかです。 –

答えて

1

はあなたのコードが間違ってたくさんのあります - 論理から(?つまり、なぜPointからCircle継承ん)構造(宣言されていないインスタンスのプロパティを使用して)には、実に奇妙な(なぜあなたが定義しているためにあなたのCircle.centerゲッターは2回ですか?) - しかし、問題のエラーの主な原因は、すべての例外をキャプチャして無視するという非常に悪い考えです。

あなたCircle.from_tuple()クラスのメソッドを呼び出すときすなわち、それが今度は新しいCircleインスタンスを作成し、その__init__()メソッドが渡されて呼び出されますが、あなたがちょうどあなたを転送しているときに、なぜあなたがCircle.from_tuple()が必要です。ところで(centerradiusに合格しました引数 - Circle()に直接電話するのはなぜですか?) (3, 4)centerとすれば、それは効果的にCircle.__init__(center=(3, 4))と呼んだかのようになります。

そしてそこには大きな問題があります。まず、super.__init__()メソッドを呼び出して、センターのxyを十分に渡すと、self.xself.yself.data(冗長ですが、入り込むことはありません)が開始されます。その後、別の構文を使用し、タプルを最初のパラメータとして渡し、今度はself.xcenter(3, 4))に変えます。しかし実際の問題は、Circle.center()セッターに同じ(3, 4)タプルを渡すと呼ばれます。あなたの方法を見て:

@center.setter 
def center(self, center): 
    if not center == (0, 0): 
     if not isinstance(center, Point): 
      raise TypeError("The center must be a Point!") 
    self._center = center 

あなたはどうなると思いますか?渡されたcenter(3, 4))は(0, 0)ではなく、もっとも間違いなくPoint(タプル)のインスタンスではないので、TypeErrorself._centerは決して設定されません。

しかし、あなたはあなたのCircle.__init__()内のすべてのUnboundLocalErrorTypeErrorAttributeError例外を捕捉し、ちょうどあなたを介してそれらを渡すことにしましたので、ごcenterが設定されていないことを知らさないので、あなたはそれをプリントアウトしようとすると飽きない、待ちますREPL Circle.__repr__()が呼び出されると、次に定義されていないCircle._centerにアクセスしようとしてしまい、良いエラーが発生します。すでにPointから継承しているので、

迅速&汚いソリューションは、ちょうど完全に中央を忘れることです - あなたはすでにself.xself.y(とself.dataそれらに基づいてリストされて)を持っているので、centerへの参照を削除しますあなたは黄金だ:

class Circle(Point): 

    def __init__(self, center=(0, 0), radius=1): 
     super(Circle, self).__init__(*center) 
     self.radius = radius 

    def __str__(self): 
     return "Circle with center at ({0}, {1}) and radius {2}".format(self.x, self.y, self.radius) 

    def __repr__(self): 
     return "Circle(center=Point({0}, {1}), radius={2})".format(self.x, self.y, self.radius) 

    @property 
    def center(self): 
     return Point(self.x, self.y) 

    @property 
    def radius(self): 
     return self._radius 

    @radius.setter 
    def radius(self, radius): 
     if radius < 0: 
      raise ValueError('The radius cannot be negative') 
     self._radius = radius 

そして今、あなたは両方の中心のためPointまたはtupleでそれをインスタンス化することができます。

さらに良い解決策は、あなたがここで達成しようとしていることを考え直して、あなたのコードにあるようなエラーをキャプチャするために良い古い試みを試みることです。

関連する問題