2017-09-06 1 views
-1

Supposons qu'il ya des classes comme celles-ci:Comment puis-je définir une variable mutable dans les extensions C qui prend une autre extension C en entrée?

cdef class parent: 
    cdef public: 
    int trait1 
    def __init__(self, num1): 
    self.trait1 = num1 

cdef class child(parent): 
    cdef public: 
    int trait2 
    def __init__(self, num1, num2): 
    super().__init__(num1) 
    self.trait2 = num2 

cdef class new_parent: 
    cdef public: 
    float new_trait 
    def __init__(self, num): 
    self.new_trait = num 

Maintenant, je veux avoir une autre classe comme celui-ci:

cdef class gui: 
    cdef public: 
    parent agent 
    def __init__(self, agent): 
    self.agent = agent 
    def change_parent(self, new_agent): # new_agent could be any of [child, parent, new_parent] 
    self.agent = new_agent 
    print(self.module) 

Dans gui classe Je déclare une variable qui pourrait obtenir une classe en entrée (entre [parent, nouveau_parent, enfant]). Le problème est que si je veux changer le gui.agent à une autre classe en fonction gui.change_parent, cette erreur se produit:

TypeError: Cannot convert _cython_magic_b6858e13e41432c14dc63fbb10e81472.new_parent to _cython_magic_b6858e13e41432c14dc63fbb10e81472.parent 

j'avais développé le même code en python, mais une telle erreur n'est jamais arrivé parce que je ne dois pas statique -type les variables de classe. alors que dois-je faire pour pouvoir modifier le gui.agent à d'autres classes de Cython? Existe-t-il une solution à ça?

Répondre

2

Vous définissez le type agent comme étant parent, ce qui lui permet d'être parent ou tout type dérivé. new_parent n'est pas de type parent et ne dérive pas de parent donc ne peut pas être affecté à agent.

Vous devez soit faire new_parent Hériter de parent, ou si vous devez retirer le spécificateur de type sur agent afin qu'il puisse accepter un objet Python (par exemple object agent).

Ce que vous ne pouvez pas faire est de spécifier un type Cython fixe pour une variable, puis espérer pouvoir assigner n'importe quel type arbitraire à cette variable.

+0

Donc vous voulez dire dans la classe 'gui' que je n'ai pas nécessairement besoin d'utiliser' cdef public: parent agent', car il serait détecté comme un objet python. Je pensais que je devais déclarer chaque variable de classe dans les classes cython –

+0

Vous devez déclarer que la variable existe, mais vous pouvez déclarer qu'il peut s'agir de n'importe quel objet Python en faisant 'cdef public: object agent' (je pense' cdef public: agent 'fonctionne aussi). – DavidW

+0

C'est exactement ce que je cherchais. Merci beaucoup mon frère. –