2012-02-18 24 views
0

MockFileクラスを作成するためにStringIOから継承しました。派生クラスには属性「name」が必要ですが、この属性を作成するとAttributeErrorがスローされます。io.StringIOは継承されたプロパティを上書きしますか?

私は__dict__ルックアップを実行し、既にname -keyが見つかっています。 __mro__を反復すると、私はクラスの明示的に読み取り専用である 'name'という名前のプロパティを見つけました。この「名前」プロパティは

  • それはsettattr割り当てで上書きしても安全であることを意図している何のため

    1. は、だから私は基本的に2つの質問がありますか?

    completnessたとえばコード:

    class MockFile(StringIO): 
        def __init__(self, name, buffer_ = None): 
         super(MockFile, self).__init__(buffer_) 
         self.name = name  
    >>> mfile = MockFile('stringio.tmp', u'#MockFile') 
    

    がにつながる:

    Traceback (most recent call last): 
        File "<stdin>", line 1, in <module> 
        File "<stdin>", line 4, in __init__ 
    AttributeError: can't set attribute 
    
  • 答えて

    1

    はPython 2.6でio.StringIOnameプロパティはioモジュール内のクラス階層から来ています。これは、継承と合成の両方で幾分複雑な設定です。nameプロパティは、基底のオブジェクトからさまざまなラッパーと特殊化に名前を伝播するために使用されます。しかし、io.StringIOの実際のプロパティはPython 2.7以降ではなくなっています。だから、あなたのサブクラスでそれをシャドーするのはいいでしょう。

    setattr()を使用して、実際の割り当て以上のプロパティを設定することはできません。settattr()と属性の割り当てはどちらも同じように動作します。プロパティの性質により、インスタンス属性でベースクラスのプロパティをシャドーするのを防ぐことができます(これ以上のことはしません)。しかし、同じ名前で独自のプロパティを定義することも、最初にプロパティを見ないようにPythonをトリックすることもできます。

    class MockFile(StringIO): 
        name = None 
        def __init__(self, name, buffer_ = None): 
         super(MockFile, self).__init__(buffer_) 
         self.name = name  
    
    +1

    インスタンス属性を持つプロパティをシャドーするというトリックは、すべてのケースで機能しません(セッターを持つプロパティでは機能しません)。 –

    関連する問題