[Python-3000] Special methods and interface-based type system

Phillip J. Eby pje at telecommunity.com
Sun Nov 26 02:52:06 CET 2006


At 07:03 PM 11/25/2006 -0500, Jim Jewett wrote:
>I had thought that you (Bill), (along with PJE) were assuming that the
>generic function or interface itself would serve to distinguish the
>namespace.  Instead of
>
>     class A(object):
>         def magic_meth_foo(self, ...):
>
>I would write
>
>     class A(object):
>         defop foo.magic_meth(self, ...)
>
>This does work, but ... code gets just a little bit longer, with the
>extra going to dots and boilerplate.  The boilerplate won't hide the
>way "__" does.  It probably shouldn't always hide, since it won't even
>be boilerplate in some cases.  But it will be boilerplate so often
>that readers will start to skim, even when they shouldn't.
>
>In the end, that extra almost-boilerplate strikes me as a very high
>price to pay, and I'm not sure it can be avoided unless Interfaces and
>Generic Functions stay relatively rare.

This isn't quite correct.  First, in the interface API I proposed, you 
could use regular methods, if you were putting them directly in the object 
class.

However, in the normal use cases for generic functions, you don't often put 
the methods directly in the classes!  As Guido mentions for e.g. __add__ 
and __radd__, you are probably defining them in some kind of glue code that 
is not of either type.

Second, for "visitor" patterns, you aren't going to be modifying the base 
types to add new methods to generic functions.  Consider, for example, the 
compiler.ast package, that has a variety of objects that represent AST 
nodes.  If you are creating a new compiler or refactoring tool or "lint" 
checker with generic functions, you'd write the functions in a new module 
for the function to be performed, and then define methods for the function 
by AST class.  You would not modify the AST classes to add "lint_me" methods!

And so it is for any other case where you are retrofitting or extending the 
behavior of existing types - making it on the whole relatively infrequent 
that you'll want to put most methods inside class bodies.  This is 
especially true in cases where you want to support your operation on 
built-in types: there's no place for you to add the code in that case.

Finally, in situations where you *do* put the methods directly on the 
class, chances are good that you'll either be adding a single operation or 
will want to just have a generic factory function to just produce an object 
that has all the desired methods in the first place.  In none of these 
cases will you have many generic function methods in a single class body.

The only case left, really, where you'd put many generic function methods 
in a class body is when they're builtins like len(), iter() etc...  which 
don't have the "namespace noise" you're worried about.



More information about the Python-3000 mailing list