Licence CC BY-NC-ND Thierry Parmentelat & Arnaud Legout
attributs et __getattr__¶
On vous demande d’écrire une classe
Echoqui répond à toutes les méthodes dont le nom fait 3 lettres
et qui dans ce cas retourne le nom de la méthode concaténé 3 fois
>>> echo = Echo()
>>> echo.foo()
'foofoofoo'
>>> echo.bar()
'barbarbar'
>>> echo.six()
'sixsixsix''Indices¶
une seule méthode
__getattr__suffitelle doit renvoyer une méthode
ou lever l’exception AttributeError
class Echo:
def __getattr__(self, attrname):
if len(attrname) == 3:
# on pourrait écrire tripler()
# mais pour inspecter ce qui nous est vraiment passé
def tripler(*args, **kwds):
# print("incoming", args, kwds)
return attrname * 3
return tripler
else:
raise AttributeError(f"No such method {attrname} length = {len(attrname)} != 3")echo = Echo()
echo.foo()'foofoofoo'echo.bar()'barbarbar'try:
echo.foobar()
except AttributeError as e:
print("OOPS", e)OOPS No such method foobar length = 6 != 3
Deuxième partie¶
on veut maintenant une classe Proxy
qu’on crée à partir d’une instance de
Echoet d’une blacklist (une liste de mots de 3 lettres)
et qui répond là encore à toutes les méthodes
dont le nom fait 3 lettres
en sous-traitant à son instance de
Echosauf pour les méthodes dans la blacklist
Indices¶
très similaire au précédent
attention à bien appeler la méthode de
echoune fois que vous l’avez localisée
>>> blacklist = [ 'six', 'two', 'four']
>>> echo2 = BlacklistEcho(blacklist)
>>> echo2.foo()
'foofoofoo'
>>> echo2.six()
... raise AttributeError
class BlacklistEcho(Echo):
def __init__(self, blacklist):
super().__init__()
self.blacklist = blacklist
def __getattr__(self, attrname):
if attrname in self.blacklist:
raise AttributeError("blacklisted method {attrname}")
return super().__getattr__(attrname)blacklist = [ 'six', 'two', 'four']
echo2 = BlacklistEcho(blacklist)
echo2.foo()'foofoofoo'try:
echo2.six()
except AttributeError as e:
print("OOPS", e)OOPS blacklisted method {attrname}
try:
echo2.foobar()
except AttributeError as e:
print("OOPS", e)OOPS No such method foobar length = 6 != 3