2012-04-27 17 views
1

別のクラスのサブクラスを呼び出すとエラーが発生しますが、直接呼び出すとエラーになります。別のクラスからこのサブクラスのインスタンスを作成すると、スーパークラスの情報がサブクラスに渡されないようです。サブクラスの呼び出し方法に依存するPython継承奇妙さ

class HBatom(object): 
    def __init__(self, struct, sele, **kwargs): 
     self.struct = struct 
     self.sele = sele 

class HDonor(HBatom): 
    def __init__(self,struct,sele,**kwargs): 
     super(HDonor,self).__init__(struct,sele,**kwargs) 
     self.find_H() 
    def find_H(self): 
     bonded = self.struct.select(''.join(["bonded to ", self.sele.getSelstr()])) 

これは

import HBonds 
HB = HBonds.HDonor(structure,Nsel,f_wat=1) 

に動作します。しかし、私はHDonorsの辞書が含まれているクラスのインスタンスを作成し、その後、私はエラーで実行

HN = HBonds.HNtwrk(structure,1) 
HN.build_HNtwrk() 

AttributeError: 'HDonor' object has no attribute 'sele' 

を取得移入することを教えたときにpdbは、2番目のケースでは自己にHBatom親クラスの属性が含まれていないことを示しています。 自己には、最初のケースではその情報が含まれていますが、2番目のケースではその情報はどのように含まれていますか?

申し訳ありませんが、私はHNtwrkを元の投稿に含めませんでした。総コードはほぼ400行であるため、必要以上に含めることは望ましくありません。 HDonor.find_Hは()HBatom属性を必要とするので、ここでHNtwrk

class HNtwrk: 
    def __init__(self,structure, f_wat = 0): 
    self.f_wat = f_wat 
    self.struct = structure 
    self.rh_o = 2.5 
    self.rn_o = 3.5 
    self.Dons = dict() 
    self.Accs = dict() 

def build_HNtwrk(self): 
    Dsele = self.struct.select(DonStr) 
    Asele = self.struct.select(AccStr) 
    self.addDons(Dsele) 
    self.addAccs(Asele) 

def addDons(self, Dsele): 
    for pairs in iterNeighbors(Dsele,self.rn_o,Asele): 
     iN = pairs[0].getIndices()[0] 
     iA = pairs[1].getIndices()[0] 

     if iN not in self.Dons: 
      Hdon = HDonor(self.struct,pairs[0].getSelstr,f_wat=self.f_wat) 
      self.Dons[iN] = Hdon 

私はHDONを設定し、コードの旅行をの関連部分があります。 HDonorインスタンスがHNtwrkから作成されたとき、HBonom .__ init __()はHDonor initの間に呼び出されないかのようです。明確にするために、HNtwrkは他のクラスと同じファイルに表示されます。

+0

コードが*完全*正確であることを確認してください。 MIはありませんか? –

+0

少なくとも、あなたはHBatom/HBatoms typoを持っています(最初は 'class 'がありません) –

+0

@ IgnacioVazquez-Abrams:MIとは何ですか?私はこれを心筋梗塞の略語として知っているだけです(申し訳ありませんが、仕事に付いています)、私はそれが他の何かを意味することを願っています。 –

答えて

0

具体的なスーパークラス名のsuperの代わりにHBatomとしてください。

あなたがsuper(HDonor, self)を呼び出し、selfが実際にHDonorの子である、superの結果は、あなたが期待通りHBatom、関数はHDonorクラスへの呼び出しではない渡します。

superが問題を引き起こす理由の詳細については、this answerを参照してください。

+0

あなたはsuperを使うことについて良い点を作っていますが、HBatomに変更する.__ init __(self、struct、sele、** kwargs)はこの場合効果がありません – johnjax

0

あなたはHNtwrkまたはbuild_HNtwrkのコードを示していないが、私はHNtwrk.__init__は親の__init__メソッドを呼び出していないことを推測します。

+0

HNtwrkはHBatomを継承せず、 'オブジェクト。私はそれが表示されるべきであることに同意する。 –

+0

私は今、HNtwrkの関連する部分を含めました。 HNtwrkはHBatomのサブクラスではないため、HBatom \ __ init__は呼び出されません。代わりに、HBatomsの辞書を含み、それらの間の関係を追跡することを意味します。 – johnjax

0

問題を解決しました。これは継承の問題ではないことが分かります。 私はこのように私は私が渡したと思ったものを渡していませんでしたし、これは下手に書かれた例外をトリガー

Hdon = HDonor(self.struct,pairs[0].getSelstr(),f_wat=self.f_wat) 

と呼ばれている必要があります代わりにその

Hdon = HDonor(self.struct,pairs[0].getSelstr,f_wat=self.f_wat) 

と呼ばれるので、私は問題を得ていましたHBatom .__ init __()(私はコードスニペットとしてインクルードできませんでした)に含まれていました。提案をした人に感謝します。将来私は問題を分離し、完全なコードを投稿する別々の小さなコードを作成します。

関連する問題