[Python-Dev] Re: closure semantics
Guido van Rossum
guido at python.org
Wed Oct 22 19:59:05 EDT 2003
> I am currently working on implementing an algorithm with the following
> properties:
> - It is an algorithm, not a data structure; that is, you run it,
> it returns an answer, and it doesn't leave any persistent state
> afterwards.
> - It is sufficiently complex that I prefer to break it into several
> different functions or methods.
> - These functions or methods need to share various state variables.
>
> If I implement it as a collection of separate functions, then there's a
> lot of unnecessary code complexity involved in passing the state
> variables from one function to the next, returning the changes to the
> variables, etc. Also, it doesn't present a modular interface to the
> rest of the project -- code outside this algorithm is not prevented from
> calling the internal subroutines of the algorithm.
>
> If I implement it as a collection of methods of an object, I then have
> to include a separate function which creates an instance of the object
> and immediately destroys it. This seems clumsy and also doesn't fit
> with my intuition about what objects are for (representing persistent
> structure). Also, again, modularity is violated -- outside code should
> not be making instances of this object or accessing its methods.
>
> What I would like to do is to make an outer function, which sets up the
> state variables, defines inner functions, and then calls those
> functions. Currently, this sort of works: most of the state variables
> consist of mutable objects, so I can mutate them without rebinding them.
> But some of the state is immutable (in this case, an int) so I need to
> somehow encapsulate it in mutable objects, which is again clumsy.
> Write access to outer scopes would let me avoid this encapsulation
> problem.
I know the problem, I've dealt with this many times. Personally I
would much rather define a class than a bunch of nested functions.
I'd have a separate master function that creates the instance, calls
the main computation, and then extracts and returns the result. Yes,
the class may be accessible at the toplevel in the module. I don't
care: I just add a comment explaining that it's not part of the API,
or give it a name starting with "_".
My problem with the nested functions is that it is much harder to get
a grasp of what the shared state is -- any local variable in the outer
function *could* be part of the shared state, and the only way to tell
for sure is by inspecting all the subfunctions. With the class,
there's a strong convention that all state is initialized in
__init__(), so __init__() is self-documenting.
--Guido van Rossum (home page: http://www.python.org/~guido/)
More information about the Python-Dev
mailing list