devork

E pur si muove

Discovering basestring

Wednesday, February 10, 2010

This may seem simple and trivial, but today I discovered the basestring type in Python. It is essentially a base type for str and unicode, which comes in handy when writing isinstance(foo, basestring) in test code for example.

Strangely, despide PEP 237 mentioning the equivalent for int and long as "integer" I can't actually find what has become of that, so still writing isinstance(foo, (int, long)) for now.

Note that this is Python 2.x only, in 3.x it's all unicode so there is no longer a need for a common base type. int and long are unified as well in Python 3.x obviously.

Registering callbacks: to quack like a duck or tell which bit will quack the duck way?

Friday, February 05, 2010

When you have someplace where you register a set of callbacks you have a few options:

  1. Use an interface-style API. I.e. you have a Mixin style class defining the methods expected to be present, probably just raising NotImplementedError. You then just pass in the entire object to the .register() function.
  2. Just try if it quacks like a duck. IMHO this is just the pythonic equivalent of the above, simply without the explicit mixin class.
  3. Explicitly pass in the callback functions. This would be something like: .register(func1, ...). Secret benefit here is using the result of functools.partial() and things like it.

What I don't like about the first two options is that you force the method name of the callback onto the user. The third option allows you to achieve the same but at the cost of a more complicated register function. But I tend to prefer it because it's more explicit and it avoids "hiding" things in the object (via the mixin) thus keeping the interfacace between caller and callee cleaner.

Are there other design considerations when making this choice? Maybe there's already an essay somewhere exploring these ideas in more detail then I'm doing here?

Subscribe to: Posts (Atom)