data validation when creating an object

Cameron Simpson cs at zip.com.au
Wed Jan 15 20:25:42 EST 2014


On 15Jan2014 20:09, Rita <rmorgan466 at gmail.com> wrote:
> I would like to do some data validation when its going to a class.
> 
> class Foo(object):
>   def __init__(self):
>     pass
> 
> I know its frowned upon to do work in the __init__() method and only
> declarations should be there.

This rule of thumb does not mean "do nothing". It may be perfetly
vaid to open file or database connections in __init__, etc, depending
on what the object is for.

The post condition of __init__ is that the object is appropriately
initialised. The definition of appropriate depends on you.

Data validation is very much an appropriate thing to do in __init__.

If it highly recommended to validate your inputs if that is feasible
and easy at __init__ time. It is far better to get a ValueError
exception (the usual exception for invalid values, which an invalid
initialiser certainly is) at object creation time than at some less
convenient time later during use.

> So, should i create a function called validateData(self) inside foo?

It might be a good idea to make a (probably private) method to check
for validity and/or integrity, eg:

  def _is_valid(self):
    ... checks here, return True if ok ...

because that would allow you to call this at arbitrary other times
if you need to debug.

However, I would also have obvious validity checks in __init__
itself on the supplied values. Eg:

  def __init__(self, size, lifetime):
    if size < 1:
      raise ValueError("size must be >= 1, received: %r" % (size,))
    if lifetime <= 0:
      raise ValueError("lifetime must be > 0, received: %r" % (lifetime,))

Trivial, fast. Fails early. Note that the exception reports the
receive value; very handy for simple errors like passing utterly
the wrong thing (eg a filename when you wanted a counter, or something
like that).

Certainly also put a test of self._is_valid() at the bottom of
__init__, at least during the debug phase. Provided _is_valid() is
cheap and fast. For example, it would be appropriate to check that
a filename was a string. It would probably (your call) be inappropriate
to open the file or checksum its contents etc etc.

Cheers,
-- 
Cameron Simpson <cs at zip.com.au>

I distrust a research person who is always obviously busy on a task.
- Robert Frosch, VP, GM Research



More information about the Python-list mailing list