Soutenez-nous
Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 5 sur 5
  1. #1
    Membre confirmé
    Inscrit en
    juin 2006
    Messages
    570
    Détails du profil
    Informations forums :
    Inscription : juin 2006
    Messages : 570
    Points : 278
    Points
    278

    Par défaut overrider __getattribute__ on the fly ?

    Bonjour,

    je sais que la fonction __getattribute__ doit être utilisée avec précaution, mais j'aurais besoin de l'écraser dans l'un de mes objets.
    Mais l'écraser que dans certain cas, donc pas à la construction de mon objet car cette decision se se fait par le model.

    Je tente donc de faire

    a = MaClass()
    a.__getattribute__ = lambda name: mafunction(name)

    Mais c'est toujours le __getattribute__ de base qui est utilisé.

    Alors je peux faire ca:

    MaClass.__getattribute__ = lambda self, name: mafunction(self, name)

    Mais j'aimerais éviter si possible.

    Est ce qu'il y a un moyen d'overrider le getattribute on the fly, ou alors une fois l'objet créé cela ne peut plus bouger ?

  2. #2
    Expert Confirmé Avatar de PauseKawa
    Homme Profil pro Patrice BLANGARIN
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    juin 2006
    Messages
    2 713
    Détails du profil
    Informations personnelles :
    Nom : Homme Patrice BLANGARIN
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : juin 2006
    Messages : 2 713
    Points : 3 900
    Points
    3 900

    Par défaut

    Bonjour,

    Une solution comme ceci ?
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    class Foo(object):
        def __len__(self):
            return 1
        def __getattribute__(*args):
            return object.__getattribute__(*args)
     
    class Bar(Foo):
        def __getattribute__(*args):
            print('bar code')
            return object.__getattribute__(*args)
     
     
    bar = Foo()
    print(bar.__len__())
    old_class = bar.__class__
    bar.__class__ = Bar
    print(bar.__len__())
    bar.__class__ = old_class
    print(bar.__len__())
    @+
    Merci d'utiliser le forum pour les questions techniques.

  3. #3
    Membre confirmé
    Inscrit en
    juin 2006
    Messages
    570
    Détails du profil
    Informations forums :
    Inscription : juin 2006
    Messages : 570
    Points : 278
    Points
    278

    Par défaut

    Ca marcherait aussi mais j'aurais preferé une solution plus dynamique. La nouvelle class ne se fera pas dans le domaine model mais au niveau datamapper.
    Mais tant pi je vais partir la dessus, merci bien !

  4. #4
    Expert Confirmé Avatar de PauseKawa
    Homme Profil pro Patrice BLANGARIN
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    juin 2006
    Messages
    2 713
    Détails du profil
    Informations personnelles :
    Nom : Homme Patrice BLANGARIN
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : juin 2006
    Messages : 2 713
    Points : 3 900
    Points
    3 900

    Par défaut

    Bonsoir,

    En fait je n'ai pas dus comprendre la différence entre a.__getattribute__ = lambda name: mafunction(name) et bar.__class__ = Bar : Que cela soit une fonction ou une classe que vous déclariez qu'importe ?
    Ceci dit si vous voulez du 'plus on the fly' vous pouvez utiliser type
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    class Foo(object):
        def __len__(self):
            return 1
        def __getattribute__(*args):
            return object.__getattribute__(*args)
     
     
    def newgetattribute(*args):
        print('bar code')
        return object.__getattribute__(*args)
     
     
    bar = Foo()
    print(bar.__len__())
    old_class = bar.__class__
    bar.__class__ = type('derived', (Foo,), {'__getattribute__': newgetattribute})
    print(bar.__class__)
    print(bar.__len__())
    bar.__class__ = old_class
    print(bar.__len__())
    print('derived' in locals())
    mais cela reviens au même si ce n'est que 'derived' ne vas pas polluer l'espace de nom.
    La solution de la classe dérivée me semble le plus propre mais il y a sans doute d'autres réponses.

    Cela correspond à la question ou je fais fausse route ?

    @+
    Merci d'utiliser le forum pour les questions techniques.

  5. #5
    Expert Confirmé Sénior
    Homme Profil pro
    Architecte technique
    Inscrit en
    juin 2008
    Messages
    4 754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Industrie

    Informations forums :
    Inscription : juin 2008
    Messages : 4 754
    Points : 7 168
    Points
    7 168

    Par défaut

    Salut,
    __getattribute__ a le défaut d'être appelé pour accéder à n'importe quel attribut d'une l'instance (y compris les méthodes).
    Si le but est de faire un "datamapper", il est plus "simple" de passer par des "descriptors": ils sont plus sélectifs.
    - W
    Architectures Post-Modernes

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •