[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