<br><br><div class="gmail_quote">On Fri, Feb 22, 2013 at 10:31 PM, Steven D'Aprano <span dir="ltr"><<a href="mailto:steve@pearwood.info" target="_blank">steve@pearwood.info</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im">On 23/02/13 10:50, neubyr wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I would like to validate data attributes before the object is instantiated<br>
or any changes thereafter. For example, following is a simple Person class<br>
with name and age attributes. I would like to validate whether age is an<br>
integer before it is added/changed in the object's dictionary. I have taken<br>
a simple integer validation example, but it could be something like<br>
DateField validation or X509 certificate validation as well. Following is<br>
my example code:<br>
<br>
<br>
class Person(object):<br>
   def __init__(self,name,age):<br>
     <a href="http://self.name" target="_blank">self.name</a> = name<br>
     self.age = age<br>
<br>
   def get_age(self):<br>
     return self._age<br>
<br>
   def set_age(self,val):<br>
     try:<br>
       int(val)<br>
       self._age = val<br>
     except ValueError:<br>
         raise Exception('Invalid value for age')<br>
</blockquote>
<br></div>
The setter is unnecessarily complicated. Just let the ValueError, or TypeError, or any other error, propagate:<br>
<br>
    def set_age(self,val):<br>
        self._age = int(val)<br>
<br>
<br>
This will allow the user to pass ages as strings, which I assume you want because that's what your code above does. instance.age = "6" will set the age to the int 6. If all you want to accept are ints, and nothing else:<br>

<br>
<br>
    def set_age(self,val):<br>
        if isinstance(val, int):<br>
            self._age = val<br>
        else:<br>
            raise TypeError('expected an int, but got %r' % val)<div class="im"><br>
<br>
<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
   def del_age(self):<br>
     del self._age<br>
<br>
   age = property(get_age,set_age,del_<u></u>age)<br>
</blockquote>
<br>
<br></div>
In general, you would leave out the property deleter. I find that in general if you're validating attributes, you want them to be present and valid, so deleting should be an error.<span class="HOEnZb"><font color="#888888"><br>

<br>
<br>
-- <br>
Steven</font></span><div class="HOEnZb"><div class="h5"><br>
</div></div></blockquote></div><br><div><br></div><div>Thank you for your comments Steven. </div><div><br></div><div>Yes, I think I should remove property deleter in this case.</div><div><br></div><div>I would like to use this Person class in another class. For example, if Person class is 'model' in a small MVC-style web application, then where should I place my validation. A view form will be passing parameters to a controller which will create and write Person objects/models. Should the validation be in place at all three levels?</div>
<div><br></div><div>I am inclined towards adding integer validation in views, but I am not sure where should I add it in a controller class. Also, it's easy to add integer validation in view form (javascript), but what if I have a more complex format - X509 certificate or  some other file-type related validation? Is it OK to validate them only in property setter methods?</div>
<div><br></div><div><br></div><div>-- N</div>