La référence de la fonction Python transmise dans le constructeur se transforme en type de données C_Void_P

StackOverflow https://stackoverflow.com/questions/8979981

  •  12-11-2019
  •  | 
  •  

Question

Pour faire une longue histoire, j'essaie de passer une liste de dictionnaires dans une classe de conteneurs, avec l'intention que chaque dictionnaire soit utilisé pour instancier une autre classe. Le problème est que chaque dictionnaire contient une référence d'objet de fonction à attribuer à la sous-classe, et pour une raison quelconque juste avant que la sous-classe la plus intérieure ne soit instanciée, elle change d'un objet de fonction Python dans un objet C_Void_P.

Le domaine d'application est la création d'une bibliothèque de widgets d'interface utilisateur basés sur du texte à l'aide de malédictions.

Voici la classe «enfant» que le conteneur est censé contenir:

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

Et voici la classe «conteneur»:

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

Pour référence, la fenêtre des classes de base et BoxedWindow peuvent être affichés ici

Lorsque j'exécute le code de test suivant, j'obtiens l'erreur suivante:

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

Erreur:

 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 révèle que la fonction est récupérée à partir du dictionnaire et est toujours un objet de fonction. Une fois qu'il est passé dans le constructeur de DigitalReadout, cependant, il revient en quelque sorte un objet C_Void_P. Des idées pourquoi cela se produit?

Merci d'avance et excuses pour la question horriblement longue.

Était-ce utile?

La solution

Ceci est le constructeur de DigitalReadout:

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

C'est comme ça que vous l'appelez:

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

On dirait que vous manquez un paramètre dans le constructeur (height?), parce que si je le lis bien, la fonction doit être data_source Et c'est maintenant digits.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top