Précédent   Forum du club des développeurs et IT Pro > Autres langages > Python & Zope > Général Python
Général Python Forum d'entraide sur les fondamentaux du langage Python, syntaxe, POO, bibliothèque standard, ...
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 13/02/2013, 23h55   #1
Djobird
Membre confirmé
 
Inscription : 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 ?
Djobird est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/02/2013, 06h44   #2
PauseKawa
Expert Confirmé
 
Avatar de PauseKawa
 
Homme Patrice BLANGARIN
Technicien Help Desk, maintenance, réseau, système et +
Inscription : juin 2006
Messages : 2 613
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 613
Points : 3 724
Points : 3 724
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.
PauseKawa est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/02/2013, 15h17   #3
Djobird
Membre confirmé
 
Inscription : juin 2006
Messages : 570
Détails du profil
Informations forums :
Inscription : juin 2006
Messages : 570
Points : 278
Points : 278
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 !
Djobird est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/02/2013, 18h54   #4
PauseKawa
Expert Confirmé
 
Avatar de PauseKawa
 
Homme Patrice BLANGARIN
Technicien Help Desk, maintenance, réseau, système et +
Inscription : juin 2006
Messages : 2 613
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 613
Points : 3 724
Points : 3 724
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.
PauseKawa est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/02/2013, 13h32   #5
wiztricks
Expert Confirmé Sénior
 
Inscription : juin 2008
Messages : 3 696
Détails du profil
Informations forums :
Inscription : juin 2008
Messages : 3 696
Points : 4 525
Points : 4 525
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
wiztricks est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 22h30.


 
 
 
 
Partenaires

Hébergement Web