I have a child class method I want to conditionally short circuit. What I'm trying to do is something like this except I want to put the validation logic into the base class.
class BaseClass(object):
def getvalue(self):
return True
def validate(self):
validated = self.getvalue()
return validated
class ExtendedClass1(BaseClass):
def do_some_work(self):
validated = self.validate()
if not validated:
print "Not validated."
return
print "Things are validated if the method got this far.", validated
class ExtendedClass2(BaseClass):
def do_some_work(self):
validated = self.validate()
if not validated:
print "Not validated."
return
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()
Following this example I was able to convert some of the repeated code into a decorator pattern.
class BaseClass(object):
def validate(input_function):
def wrapper(*args,**kwargs):
validated = True
if not validated:
print "Not validated."
return
input_function(*args, **kwargs)
return wrapper
validate = staticmethod(validate)
class ExtendedClass1(BaseClass):
@BaseClass.validate
def do_some_work(self):
print "Things are validated if the method got this far."
class ExtendedClass2(BaseClass):
@BaseClass.validate
def do_some_work(self):
print "Things are validated if the method got this far."
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()
However, I need to call a method of the base class in the decorator to do the validation work, and retrieve the value of (validated) in the child class. Following this example here, I modified the decorator in an attempt to let it call self.getvalue(). At this point it doesn't error out, but it doesn't work either because self.getvalue() doesn't return True. This is starting to seem like more trouble than it's worth, but now I'm curious as to whether or not it's possible.
class BaseClass(object):
def getvalue(self):
return True
def validate(self):
def wrap(input_function):
def wrapper(*args,**kwargs):
validated = self.getvalue()
if not validated:
print "Not validated."
return
input_function(*args, **kwargs)
return wrapper
return wrap
validate = staticmethod(validate)
class ExtendedClass1(BaseClass):
@BaseClass.validate
def do_some_work(self):
print "Things are validated if the method got this far."#, validated
class ExtendedClass2(BaseClass):
@BaseClass.validate
def do_some_work(self):
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()
Is it possible to set an attribute with the decorator and then retrieve it later?
...
self.validated = True
if not self.validated:
print "Not validated."
return
...
print work1.validated
...
AttributeError: 'ExtendedClass1' object has no attribute 'validated'
Essentially, I want to turn this:
class ExtendedClass1(BaseClass):
def do_some_work(self):
validated = self.validate()
if not validated:
print "Not validated."
return
print "Things are validated if the method got this far.", validated
Into this:
class ExtendedClass1(BaseClass):
@BaseClass.validate
def do_some_work(self):
print "Things are validated if the method got this far.", validated
Using the suggestion posted by Zaur Nasibov, this example satisfies my use case. I'm still interested to know if @validate can be implemented as a method instead of a stand alone function, but this gets the job done.
class BaseClass(object):
def getvalue(self):
return True
def validate(func):
def wrapped(self, *args, **kwargs):
validated = self.getvalue()
self.validated = validated
if not validated:
print "Not validated."
return
func(self, *args, **kwargs)
return wrapped
class ExtendedClass1(BaseClass):
@validate
def do_some_work(self,input):
print "Things are validated if the method got this far.", self.validated, input
class ExtendedClass2(BaseClass):
@validate
def do_some_work(self):
print "Things are validated if the method got this far.", self.validated
class ExtendedClass3(BaseClass):
def do_some_work(self):
print "This one doesn't require validation."#, self.validated
work1 = ExtendedClass1()
work1.do_some_work(input="some text")
work2 = ExtendedClass2()
work2.do_some_work()
work3 = ExtendedClass3()
work3.do_some_work()