2016-08-15 22 views
2

最初に、私はPythonには新しかったと言及する必要があります。私はコンテナをコンテナの中に入れようとしていますが、そうすると無限のコンテナが返ってきます。オブジェクトを入れ子にしたときの無限再帰

class Container(Drawable): 

    content = [] 

    # some more code  

    def append(self, obj): 
     print(obj.content) 
     self.content.append(obj) 
     print(self.content[0].content) 

ページはコンテナと似ています。それらの両方が同じ

[] 
[<src.test.container.Container object at 0x013550D0>] 

する必要がありますので、コンテナは、すでに間違っている次のことを、印刷し内部で私は

を、それをプリントアウトするために、このメソッドを使用して、いくつかの要素

pa = Page() 
ca = Container(color="red") 
cb = Container(color="blue") 
ca.append(cb) 
pa.append(ca) 

追加を追加します

class SomeClass(): 

    def __init__(self, page): 

     self.print_content(page, 0) 


    def print_content(self, parent, depth): 
     depth += 1 
     for obj in parent.content: 

      print((str(depth).rjust(depth, ' ') + " " + str(obj)).rjust(depth, ' ')) 

      if(depth > 5): # to stop infinite recursion in print 
       return 
      self.print_content(obj, depth) 

次のようなことがありますが、意味をなさない。私はコンテンツの中に自分自身の内部にcaを追加したことはありませんでしたが、追加すると起こります。

1 Container [color=red ] 
2 Container [color=blue ] 
    3 Container [color=blue ] 
    4 Container [color=blue ] 
    5 Container [color=blue ] 
    6 Container [color=blue ] 

これはなぜ起こっているのですか?ページに2つのコンテナを追加すると、それは問題ありませんが、ネストするとすぐに無限再帰になります。また、青色のコンテナはすべて同じ(住所)です。私はそれが明らかな間違いのように感じますが、私はそれを理解することができません

+2

あなたは**クラス**レベル属性として 'content'を定義しました。だから、単一のインスタンスのためにそれを修正しようとすると*すべての*インスタンスのためにそれを変更し、あなたが見ている動作につながる。 –

+1

私はContainerに対して 'def __init __(self):self.content = []'を実行しました。ありがとう!私はそれを受け入れることができるように答えとしてそれを追加してください –

答えて

2

Containerクラスではとしてcontentを定義しています。

つまり、Containerの複数のインスタンスが存在する場合でも、それらはすべて同じ変更可能なcontentリストを共有します。そのリストを変更すると(self.content.append()Container.content.append()であるかに関係なく)、そのリストはのすべてに変更されます。代わりに__init__()でのインスタンスの属性として

初期化content:。

class Container(Drawable): 

    def __init__(self, *args, **kwargs): 
     super(Container, self).__init__(*args, **kwargs) 
     self.content = [] 

(私はあなたのDrawableクラスがどのようなものかわからないのでsuper(Container, self).__init__(*args, **kwargs)呼び出しがあることもそのintitialiserが呼ばれているが必要になることがあります、 self.contentを初期化する前に、すべての位置とキーワードの引数を受け入れているだけです。

関連する問題