OVH Cloud OVH Cloud

classe et données membres

16 réponses
Avatar
JBB
J'aimerai pouvoir empêcher d'ajouter des données membres/
exemple:
class A:
pass

x = A()
x.name = "toto" # crée une nouvelle donnée membre, uniquement sur l'objet x.

je prefererais faire un truc du genre:

class A:
def __init__(self):
self.name = ""

x = A()
x.name = "toto" # ok
x.truc = 1 # génère une exception

Est ce que c'est possible de faire ça en python?

6 réponses

1 2
Avatar
Olivier Ravard
William Dode wrote:
Ton raise ne raise rien du tout ?


Oui, raccourci approximatif je te l'accorde.
J'aurais dû mettre raise AttributeError "..."

Une variante qui raise toute seule comme une grande

class Class1:

list_attr = {'name':None,
'other':None}

def __getattr__(self, attr):
return Class1.list_attr[attr]

def __setattr__(self, attr, value):
Class1.list_attr[attr]
Class1.list_attr[attr]=value



C'est mieux.

Avatar
Bruno Desthuilliers
Olivier Ravard wrote:

Bruno Desthuilliers wrote:

(snip)




Utiliser __getattr__



Pour empêcher de *créer* un nouvel attribut ?


bien sûr.


Et pour une réponse plus complète, voici un petit exemple sur lequel
on peut discuter pour proposer une meilleure implémentation :

class Class1:


class Class1(object):

list_attr = {'name':None,
'other':None}


list_attr = ['name', 'other']

# inutile
#> def __getattr__(self, attr):
#> if attr in Class1.list_attr:
#> return Class1.list_attr[attr]
#> else:
#> raise

raise quoi ?

def __setattr__(self, attr, value):
if attr in Class1.list_attr:
if attr in self.list_attr:

Class1.list_attr[attr]=value
object.__setattr__(self, attr, value)


else:
raise
raise AttributeError("object %s has no attribute %s" %

(self.__class__, attr))

Franchement, tu te compliques inutilement la vie. Et bien sûr, c'est
__setattr__ qui empêche qu'on crée un nouvel attribut, pas __getattr__.




Avatar
Olivier Ravard
Bruno Desthuilliers wrote:
Olivier Ravard wrote:

Bruno Desthuilliers wrote:

(snip)




Utiliser __getattr__



Pour empêcher de *créer* un nouvel attribut ?


bien sûr.


Et pour une réponse plus complète, voici un petit exemple sur lequel
on peut discuter pour proposer une meilleure implémentation :

class Class1:


class Class1(object):

list_attr = {'name':None,
'other':None}


list_attr = ['name', 'other']

# inutile
#> def __getattr__(self, attr):
#> if attr in Class1.list_attr:
#> return Class1.list_attr[attr]
#> else:
#> raise

raise quoi ?

def __setattr__(self, attr, value):
if attr in Class1.list_attr:
if attr in self.list_attr:

Class1.list_attr[attr]=value
object.__setattr__(self, attr, value)

else:
raise
raise AttributeError("object %s has no attribute %s" %

(self.__class__, attr))

Franchement, tu te compliques inutilement la vie. Et bien sûr, c'est
__setattr__ qui empêche qu'on crée un nouvel attribut, pas __getattr__.


c'est évident. Dans mon esprit, quand je disais d'utiliser __getattr__ cela voulait
dire "le couple __getattr__ __setattr__".





Avatar
Bruno Desthuilliers
Bruno Desthuilliers wrote:


Olivier Ravard wrote:

Bruno Desthuilliers wrote:

(snip)



Utiliser __getattr__


Pour empêcher de *créer* un nouvel attribut ?


bien sûr.


(snip)




Franchement, tu te compliques inutilement la vie. Et bien sûr, c'est
__setattr__ qui empêche qu'on crée un nouvel attribut, pas __getattr__.


c'est évident. Dans mon esprit, quand je disais d'utiliser __getattr__
cela voulait
dire "le couple __getattr__ __setattr__".


Ce n'est peut-être pas si évident pour un débutant !-)

Et surtout, il n'y a aucun besoin d'utiliser __getattr__ , ça n'aboutit
qu'à complexifier arbitrairement le code - et en l'occurrence à
introduire un joli bug, puisqu'avec ta solution, la classe devient un
borg (ie: toutes les instances partagent les mêmes valeur d'attributs...).

Bref, encore une fois, plus on fait simple, mieux ça marche...






Avatar
Olivier Ravard
Bruno Desthuilliers wrote:
Bruno Desthuilliers wrote:


Olivier Ravard wrote:

Bruno Desthuilliers wrote:

(snip)



Utiliser __getattr__


Pour empêcher de *créer* un nouvel attribut ?


bien sûr.


(snip)




Franchement, tu te compliques inutilement la vie. Et bien sûr, c'est
__setattr__ qui empêche qu'on crée un nouvel attribut, pas __getattr__.


c'est évident. Dans mon esprit, quand je disais d'utiliser __getattr__
cela voulait
dire "le couple __getattr__ __setattr__".


Ce n'est peut-être pas si évident pour un débutant !-)

Et surtout, il n'y a aucun besoin d'utiliser __getattr__ , ça n'aboutit
qu'à complexifier arbitrairement le code - et en l'occurrence à
introduire un joli bug, puisqu'avec ta solution, la classe devient un
borg (ie: toutes les instances partagent les mêmes valeur d'attributs...).



C'est bien (mon interprétation) de ce qui était demandé initialement ...

Bref, encore une fois, plus on fait simple, mieux ça marche...








Avatar
Bruno Desthuilliers
Bruno Desthuilliers wrote:

(snip)

et en
l'occurrence à introduire un joli bug, puisqu'avec ta solution, la
classe devient un borg (ie: toutes les instances partagent les mêmes
valeur d'attributs...).



C'est bien (mon interprétation) de ce qui était demandé initialement ...

Alors relis... La demande de l'OP était d'empêcher d'ajouter de nouveaux

attributs à une instance.


1 2