2010-03-10 5 views
0

Tout d'abord, je ne sais pas si c'est la bonne approche. Je veux écrire une classe de décorateur qui sera utilisée avec des méthodes d'autres classes. Avant d'exécuter la méthode, j'aimerais vérifier si toutes les variables de classe requises sont initialisées. L'idéal serait quelque chose de similaire à ceci:Classe décorateur pour tester les variables de classe requises

class Test(object): 
    def __init__(self, f): 
     self.f = f 
     # some magic 

    def __call__(self): 
     self.f.magically_get_variable(required) 
     # do some checks and execute method or throw an exception 

class Data(object): 
    def __init__(self, a, b): 
     self.a = a 

    @test 
    def sum(self): 
     required('self.a', 'self.b') 
     return self.a + self.b 

Si cela est la façon dont il devrait être fait s'il vous plaît me conseiller sur la façon de le faire correctement.

Répondre

1

Je dirais que les décorateurs sont un peu inaptes ici dans le but de vérifier si une variable existe. Réfléchissez à ce que vous envisagez de faire si les variables requises ne sont pas fournies: déclenchez une exception (dans votre commentaire).

Je dirais que (basé sur le code ci-dessus):

def sum(self): 
    return self.a + self.b 

Et laisser échouer si self.a ou self.b ne sont pas fournis (il déclenche une exception NameError, vous pouvez attraper que si vous voulez, et vous pouvez augmenter votre propre alors si vous voulez)

+0

+1: 'NameError' vous en dit plus que tout décorateur. C'est intégré. Cela fonctionne toujours. –

0

Si vous insistez sur la vérification avant que le corps de la méthode décorée commence, ce qui suit est une façon raisonnable de le faire ...:.

import functools 

class test(object): 
    def __init__(self, requiredvars): 
     self.reqs = requiredvars.split() 

    def __call__(self, f): 
     @functools.wraps(f) 
     def wrapper(wself, *a, **k): 
      missing = set() 
      for v in self.reqs: 
      if not hasattr(wself, v): 
       missing.add(v) 
      if missing: 
      msg = 'missing fields: %s' % ','.join(sorted(missing)) 
      raise valueerror, msg 
      return f(wself, *a, **k) 
     return wrapper 

class data(object): 
    def __init__(self, a, b): 
     self.a = a 

    @test('a b') 
    def sum(self): 
     return self.a + self.b 

d = data(23, 42) 
d.sum() 

Ce émet, comme vous le désirez apparemment,

Traceback (most recent call last): 
    File "rev.py", line 29, in <module> 
    d.sum() 
    File "rev.py", line 16, in wrapper 
    raise ValueError, msg 
ValueError: Missing fields: b 
Questions connexes