The reference to the Python function passed to the constructor turns into the c_void_p data type

In short, I am trying to pass a list of dictionaries to a container class with the intention that each dictionary be used to instantiate another class. The problem is that each dictionary contains a reference to a function object that must be assigned to a subclass, and for some reason, just before an instance of the innermost subclass, it passes from the python function object to the c_void_p object.

An application domain is to create a library of text custom widgets using curses.

Here is the "child" class that the container should contain:

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__() 

And here is the class 'container':

 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)) 

For reference, the base classes Window and BoxedWindow can be viewed here.

When I run the following test code, I get the following error:

 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() 

Error:

  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 shows that the function is retrieved from the dictionary and is still a functional object. However, when it is passed to the constructor for DigitalReadout, it somehow returns the c_void_p object. Any ideas why this is happening?

Thanks in advance and apologize for the terribly long question.

+4
source share
1 answer

This is the DigitalReadout constructor:

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

Here is what you call it:

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

It looks like you don't have a parameter in the constructor ( height? ), Because if I read it correctly, the function should be data_source , and now it is digits .

+3
source

Source: https://habr.com/ru/post/1392574/


All Articles