2012-01-23 10 views
4

長い話を簡単にするために、コンテナクラスに辞書のリストを渡そうとしていますが、各辞書を使用して別のクラスをインスタンス化します。問題は、各ディクショナリにサブクラスに割り当てられる関数オブジェクト参照が含まれていることです。何らかの理由で最も内側のサブクラスがインスタンス化される直前に、Python関数オブジェクトからc_void_pオブジェクトに変更されます。コンストラクタに渡されるPython関数のリファレンスがc_void_pデータ型に変わる

アプリケーションドメインは、cursesを使用してテキストベースのUIウィジェットのライブラリを作成することです。ここで

は、コンテナを含むように意図された「子」クラスです:

class DigitalReadout(Window): 
    # Just a one-line borderless window displaying some data... 
    def __init__(self, width, y, x, label, digits, data_source, parent=None): 

     super(DigitalReadout, self).__init__(1, width, y, x, parent) 

     self.data_source = data_source 
     self.data = self.get_data_from_source() 
     self.label = label 
     self.digits = digits 
     self.spaces = self.width - len(self.label) - self.digits # Calc Number of extra spaces 

    ###Irrelevant display-related classes omitted### 

    def update_data(self): 
     self.data = self.get_data_from_source() #return data from function 

    def get_data_from_source(self): 
     return self.data_source.__call__() 

そしてここでは、「コンテナ」クラスです。参考のため

class ReadoutPanel(BoxedWindow): 

    def __init__(self, y, x, readouts, parent=None): 

     super(ReadoutPanel,self).__init__(2 + len(readouts), self.find_longest_readout_width(readouts) + 2, y, x, parent) 
     self.children = [] 
     self.initialize_readouts(readouts) 

    def find_longest_readout_width(self, readouts): 
     #Find the longest member and size container accordingly 
     longest_length = 0 
     for each_dict in readouts: 
      this_dict_length = each_dict['digits'] + len(each_dict['label']) + 1 
      if this_dict_length > longest_length: 
       longest_length = this_dict_length 
     return longest_length 

    def initialize_readouts(self, readouts): 
     y_readout_index = 1 
     for each_hash in readouts: 
      function = each_dict['func'] 
      function() 
      self.children.append(DigitalReadout(each_dict['digits'] + len(each_dict['label']) + 1, 
               1, 
               y_readout_index, 
               1, 
               function, 
               self.window)) 

、基底クラスのウィンドウとBoxedWindowが表示されるhere

次のテストコードを実行すると、次のエラーが表示されます。

if __name__ == '__main__': 

    #standard cuses initialization here... 

    from time import clock 

    i = 0 

    def print_i(): 
     return str(i) 

    readouts = [{'label': 'count', 
       'digits': 10, 
       'func': print_i}, 
       {'label': 'clock', 
       'digits':10, 
       'func': print_i}] 

    readout_panel = ReadoutPanel(1, 1, readouts) #Initialize that puppy! 


    curses.endwin() 

エラー:

Traceback (most recent call last): 
File "window.py", line 515, in <module> 
readout_panel = ReadoutPanel(1, 1, readouts) 
File "window.py", line 455, in __init__ 
self.initialize_readouts(readouts) 
File "window.py", line 476, in initialize_readouts 
self.window)) 
File "window.py", line 183, in __init__ 
self.data = self.data_source() 
TypeError: 'c_void_p' object is not callable 

Printlining関数が辞書からフェッチされていることを明らかにし、依然として機能オブジェクトです。しかし、それがDigitalReadoutのコンストラクタに渡されると、何とかc_void_pオブジェクトが返されます。これがなぜ起こっているのか?

おかげさまで、恐ろしく長い質問のお詫び申し上げます。

+1

ここに何か不足していますか? 5つ目は 'function'で6つの値を' DigitalReadout'に渡しています。 'DigitalReadout'の' __init__'によると、5番目のパラメータは 'data_source'ではなく' digits'です。だからあなたは 'function()'ではなく 'self.window()'をやろうとしています。 – Avaris

+0

@Avaris、あなたは速すぎます! ;) –

+0

Egads私はとても馬鹿げている。これを指摘する時間をとっていただきありがとうございます、エラーの愚かさにも恵まれています。 – Chazu

答えて

3

これはDigitalReadoutのコンストラクタです:

def __init__(self, width, y, x, label, digits, data_source, parent=None) 

これは、あなたがそれを呼び出す方法です:あなたは、コンストラクタ(height?)でパラメータが欠落しているよう

DigitalReadout(each_dict['digits'] + len(each_dict['label']) + 1, # width 
             1,      # y 
             y_readout_index,   # x 
             1,      # label 
             function,     # digits 
             self.window)    # data_source 

はルックス、もしので、Iそれを正しく読んで、関数はdata_sourceで、今はdigitsです。

+0

お元気です。神様は、自分自身のような重度の認知障害を助けてくれることを祝福します。私はこれを忘れないでしょう! – Chazu

関連する問題