Re: repr question

Jim Roskind (jar@infoseek.com)
Wed, 20 Jul 1994 15:33:44 -0700

> From: monty@tbyte.com (Monty)
> Date: Thu, 14 Jul 1994 19:30:58 GMT
>
> A typical repr from the demo is:
>
> class complex:
> ..
> def __repr__(self):
> return 'complex' + `self.re, self.im`
>
> To be able to create the object from it's repr implies that instead of
> "import complex" you need to do "from complex import *". Is that pretty
> much standard practice, or would it make sense for repr to reference it's
> module?
>
> def __repr__(self):
> return 'complex.complex' + `self.re, self.im`

I had to face this problem as I wrote some persistent object code. I
think that the latter is better than the former, because it puts fewer
assumptions on what is in the name space (dictionary) at evaluation
time. I think there is an improvement to be had on the latter.

In general, it should be the case (IMHO) that exec'ing the repr string
should create an instance of something that (at a minimum) compares
equal with the original. The first example requires that the
constructor for the class (complex) reside in the name space
(dictionary) at exec time. Such an assumption hints that perhaps as
much as *all* the functions/methods of the module "complex" appear in
the exec time dictionary (indeed, this is what you provided with the
import ... *). This represents a *lot* of name pollution (IMHO). The
second example reduces the name pollution to requiring that the module
"complex" be known in the exec time dictionary. This is a big
improvement, but still a bit of a problem. If you assume that you
have many such modules, with "interesting" repr functions, then you
would have to pollute your global name space with all such module
names. Following the old saying that "there are few problems than an
extra level of indirection won't solve," the solution is to introduce
a function that finds an arbitrary module. The repr function would
then look like:

def __repr__(self):
return 'Module("complex").complex' + `self.re, self.im`

The advantage of such an approach is that *only* the function "Module"
must visible (re: current symbol table dictionary) at exec time. The
"Module()" function simply looks up its argument to see if it has been
imported (and proceeds to import it if it hasn't already been loaded).
Having located the module in the sys.module dictionary, it returns a
reference to the significant module.

In summary, this final version has the advantage that only a single
standard function is needed to pollute the name space. ... and you
can never know when such a function might become a standard part of
python :-) (I can wish, can't I :-) ).

Jim

Jim Roskind
voice: 408.982.4469
fax: 408.986.1889
jar@infoseek.com