__setattr__ et mécanismes de sous reférencement
Bonjour à tous,
Je m'excuse par avance si le problème que je vais exposer a déjà été traité sur le forum. J'avoue ne rien avoir trouvé de mon côté bien que vous allez voir que c'est assez basique.
Voici donc ce que je cherche à faire. J'ai une classe MaClasse qui possède, entre autre (pour l'exemple on va dire qu'il n'y a que lui), un attribut contenant une liste d'entiers (la liste peut être vide). Voici donc le code associé :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
class MaClasse:
def __init__( self, LL ):
self.L = LL
# Verification que la liste self.L contienne uniquement des entiers
self.check()
# On verifie que self.L est une liste et qu'elle est composee d'entiers
def check( self ):
if not isinstance( self.L, list ):
raise AttributeError
for n in self.L:
if not isinstance( n, int ):
raise AttributeError
def __str__( self ):
return "self.L = %s" % ( self.L, )
def __repr__( self):
return str( self ) |
Donc voila, je suis content si je tape :
Code:
1 2 3 4 5 6 7 8 9 10 11 12
|
>>> MaClasse( [] )
self.L = []
>>> MaClasse( [ 1, 2, -3 ] )
self.L = [1, 2, -3]
>>> MaClasse( "a" )
AttributeError: l'attribut doit etre de type list
>>> MaClasse( [ 1, 2, 3.14 ] )
AttributeError: les elements doivent etre entiers |
Ca a donc l'air de rouler... sauf que si je fais :
Code:
1 2 3 4
|
>>> a = MaClasse( [] )
>>> a.L = [ "a", 2 ]
self.L = ['a', 2] |
Et là, c'est gênant. Du coup, je panique pas et je définis la méthode spéciale __setattr__ pour gérer le comportement de self.L = xxx. Voila ce que je propose :
Code:
1 2 3 4 5 6 7
|
def __setattr__( self, name, value ):
if name == "L":
self.__dict__[ "L" ] = value
self.check()
else:
raise AttributeError, "L'attribut %s n'existe pas" % (name, ) |
Maintenant, ça marche je peux faire tranquillement :
Code:
1 2 3 4
|
>>> a = MaClasse( [] )
>>> a.L = [ "a", 2 ]
AttributeError: les elements doivent etre entiers |
Par contre, et c'est là que je sèche, si je fais :
Code:
1 2 3 4 5
|
>>> a = MaClasse( [] )
>>> a.L = [ 1, 2 ]
>>> a.L[ 1 ] = "a"
self.L = [1, 'a'] |
Je ne lève malheureusement pas d'exception.
Je me tourne donc vers vous pour savoir si vous connaissez la méthode "officielle" pour traiter cette problématique de maintien d'intégrité d'objet lors d'affectation.
Merci d'avance, en espérant avoir été assez clair sur mon problème.
Waste.