Python style: to check or not to check args and data members
Robert Kern
robert.kern at gmail.com
Thu Aug 31 19:56:26 EDT 2006
Joel Hedlund wrote:
> Hi!
>
> The question of type checking/enforcing has bothered me for a while, and
> since this newsgroup has a wealth of competence subscribed to it, I
> figured this would be a great way of learning from the experts. I feel
> there's a tradeoff between clear, easily readdable and extensible code
> on one side, and safe code providing early errors and useful tracebacks
> on the other. I want both! How do you guys do it? What's the pythonic
> way? Are there any docs that I should read? All pointers and opinions
> are appreciated!
Short answer: Use Traits. Don't invent your own mini-Traits.
(Disclosure: I work for Enthought.)
http://code.enthought.com/traits/
Unfortunately, I think the standalone tarball on that page, uh, doesn't stand
alone right now. We're cleaning up the interdependencies over the next two
weeks. Right now, your best bet is to get the whole enthought package:
http://code.enthought.com/ets/
Talk to us on enthought-dev if you need any help.
https://mail.enthought.com/mailman/listinfo/enthought-dev
Now back to Traits itself:
Traits does quite a bit more than "type-checking," and I think that is its
least-useful feature that it provides for Python users. Types are very
frequently exactly the wrong thing you want to check for. They allow inputs that
you would like to be invalid and disallow inputs that would have worked just
fine if you had relied on duck-typing. In general terms, Traits does
value-checking; it's just that some of the traits definitions check values by
validating their types.
You have to be careful with type-checking, because it can introduce fragility
without enhancing safety. But sometimes you are working with other code that
necessarily has type requirements (like extension code), and moving the
requirements forward a bit helps build usable interfaces.
Your examples would look like this with Traits:
from enthought.traits.api import HasTraits, Int, method
class MyClass(HasTraits):
"""My example class.
"""
int_member = Int(0, desc="I am an integer")
method(None, Int)
def process_data(self, data):
"""Do some data processing.
"""
self.int_member += 1
a = MyClass(int_member=9)
a = MyClass(int_member='moo')
"""
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "/Users/kern/svn/enthought-lib/enthought/traits/trait_handlers.py", line
172, in error
raise TraitError, ( object, name, self.info(), value )
enthought.traits.trait_errors.TraitError: The 'int_member' trait of a MyClass
instance must be a value of type 'int', but a value of moo was specified.
"""
# and similar errors for
# a.int_member = 'moo'
# a.process_data('moo')
The method() function predates 2.4 and has not yet been converted to a
decorator. We don't actually use it much.
--
Robert Kern
"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco
More information about the Python-list
mailing list