Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>How about only calling the decorated method if it has been validated? You can pass the return value of the <code>validate</code> method along if you like:</p> <pre><code>class BaseClass(object): def getvalue(self): return True def validate(input_function): def wrapper(self, *args, **kwargs): self.validated = self.getvalue() if not self.validated: print "Not validated." return input_function(self, validated=self.validated, *args, **kwargs) return wrapper validate = staticmethod(validate) class ExtendedClass1(BaseClass): @BaseClass.validate def do_some_work(self, validated=None): print "Things are validated if the method got this far.", validated class ExtendedClass2(BaseClass): @BaseClass.validate def do_some_work(self, validated=None): print "Things are validated if the method got this far.", validated class ExtendedClass3(BaseClass): def do_some_work(self): print "This one doesn't require validation." work1 = ExtendedClass1() work1.do_some_work() work2 = ExtendedClass2() work2.do_some_work() work3 = ExtendedClass3() work3.do_some_work() </code></pre> <p>The key here is adding <code>self</code> to the <code>wrapper</code> function. What happens is that your decorated functions do not get bound to the instance (and become methods), but the function returned by the decorator (<code>wrapper</code> in the above example) get's bound instead. So this function will get the <code>self</code> (the instance) parameter passed in when called! It's important to remember that what a <code>@decorator</code> does is simply call <code>decorator</code> passing in the function you are decorating, and then <em>replace</em> the function you are decorating with whatever the decorator returned. In your example this is <code>wrapper</code>, and to the class, there is no difference between that and the original function before decorating.</p> <p>In the above example, I declared <code>self</code> explicitly. If we hadn't, we could also have just taken it from <code>args</code>:</p> <pre><code>def validate(input_function): def wrapper(*args, **kwargs): print "args[0] is now the instance (conventionally called 'self')", args[0] self = args[0] self.validated = self.getvalue() if not self.validated: print "Not validated." return input_function(validated=self.validated, *args, **kwargs) </code></pre> <p>Also note that we pass an extra keyword argument to the wrapped method, named <code>validated</code>. This is entirely optional, you can just drop the <code>validated=self.validated</code> and <code>validated=None</code> parts from the example. </p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload