Metaclass, modifier les attributs de classe

L'auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Bonjour,

J'utilise python 2.7 et mon but est de reifier automatiquement les attributs d'une classe (c'est a dire encapsuler la valeur de cet attribut dans une classe minimale creee pour l'occasion).

Malheureusement, cela ne fonctionne pas et j'ai du mal a voir pourquoi, n'etant pas forcement familie avec les subtilites des metaclasses:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
def myListPrint(self): # Juste de quoi afficher les instances
    return 'value: {0}\nfilter: {1}'.format(self.value, self.filter)

class MetaClassify(type): # Metaclasse dont le but est remplacer les attributs de classe par un objet classe
    def __init__(cls, name, bases, nmspc):
        for e in [a for a in nmspc if not(a[0].startswith('_'))]:
            nmspc[e] = type(e, (object,), {'value': e, 'filter': None, '__repr__':myListPrint})
        print nmspc # Ici on voit bien que l'attribut a ete modifie
        super(MetaClassify, cls).__init__(name, bases, nmspc)

class MyList: # Un exemple de classe avec des attributs a modifier
    __metaclass__ = MetaClassify
    MyParam = 'Test'

if __name__ == "__main__":
    print type(MyList.MyParam), MyList.MyParam # Toujours une chaine de characteres au lieu d'une classe.

Merci de votre aide.

Édité par KFC

+0 -0

Cette réponse a aidé l'auteur du sujet

Bonjour,

Au moment de l'__init__, la classe est déjà créée, et il est donc trop tard pour l'altérer à partir du dictionnaire d'attributs.

Il faut donc plutôt implémenter une méthode __new__ dans ta métaclasse, qui fera globalement la même chose que ton __init__ actuel, en modifiant en conséquence l'appel à super.

Staff

Cette réponse a aidé l'auteur du sujet

Je ne saisis pas bien ce que tu cherches à faire.

Par contre instinctivement j'aurais plutôt tendance à surcharger __new__ plutôt que __init__ dans la métaclasse.

Edit: grilled.

I was a llama before it was cool

+0 -0
Auteur du sujet

Effectivement, il fallait surchager __new__.

Pour l'explication, ce que je fais c'est que je transforme ceci:

1
2
3
class Alphabet:
    A = 'a'
    B = 'b'

Vers ceci :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class Alphabet:
    class A:
        def __init__():
            self.value = a
            self.filter = None
        [...]
    class B:
        def __init__():
            self.value = b
            self.filter = None
        [...]

Evidemment juste comme cela, l'utilite ne semble pas tout a fait evidente. :)

Apres on peut s'amuser a surcharger les objets, ajouter plus d'attributs et methodes, etc.

+0 -0
Staff

Cette réponse a aidé l'auteur du sujet

On est d'accord que tu viens de déterrer un sujet datant d'avril dernier pour faire une blague (je dirai bien pas drôle, mais ce serait l’hôpital que se moque de la charité) ?

Édité par Gabbro

Hier, dans le parc, j'ai vu une petite vieille entourée de dinosaures aviens. Je donne pas cher de sa peau.

+0 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte