Easier to Ask Forgiveness than Permission (was: Newbie: static typing?)

Ben Finney ben+python at benfinney.id.au
Tue Aug 6 18:23:04 EDT 2013


Rui Maciel <rui.maciel at gmail.com> writes:

> Gary Herron wrote:
>
> > The Pythonic way is to *enjoy* the freedom and flexibility and power
> > of dynamic typing. If you are stepping out of a static typing
> > language into Python, don't step just half way. Embrace dynamic
> > typing. (Like any freedom, it can bite you at times, but that's no
> > reason to hobble Python with static typing.)
>
> What's the Python way of dealing with objects being passed to a
> function that aren't of a certain type, have specific attributes of a
> specific type, nor support a specific interface?

Python has strong typing. That means every Python object (and in Python,
every value is an object) knows what its type is and therefore what
behaviours it supports.

Types (that is, classes; the two terms refer to the same thing in
Python) are the correct place to put checks on whether the type's
instances are being used properly.

Don't check types of objects in every place where you use those objects.
(This is a sub-set of Look Before You Leap programming, which is
discouraged because it makes your code far too heavy on checking for
problems rather than the purpose of the code.)

Check for type appropriate usage in the type itself.

So the Pythonic way to deal with objects that don't support particular
behaviour is: Use the object on the assumption that it supports the
behaviour you want – that is, assume the caller of your function is
giving you an object that your function can use. If the object doesn't
support that behaviour, an error will be raised from the type.

Sometimes your function will know exactly what to do with an error, and
can give more specific information about the problem. In those cases,
you should catch the exception and ‘raise MoreSpecificError("foo") from
exc’. But only in those cases where your function *actually does* know
more about the problem.

In the majority of cases, don't check the type at all, and allow the
type-specific error to raise back to the caller, who then has to deal
with the fact they've passed your function an object that doesn't
support the necessary behaviour.

This principle – of assuming the behaviour is supported, and having a
robust infrastructure for dealing with errors – is known as Easier to
Ask Forgiveness than Permission.

In Python, we discourage LBYL and encourage EAFP. Our code tends to have
a lot less boiler-plate and obfuscatory error-checking as a result, and
tends to be more expressive than statically-typed languages.

-- 
 \       “If you make people think they're thinking, they'll love you; |
  `\     but if you really make them think, they'll hate you.” —Donald |
_o__)                                             Robert Perry Marquis |
Ben Finney




More information about the Python-list mailing list