Overloading =

Michael Hudson mwh21 at cam.ac.uk
Fri Feb 18 19:48:17 CET 2000


jhefferon at my-deja.com writes:

> In article <m3bt5fo1lk.fsf at atrus.jesus.cam.ac.uk>,
>   Michael Hudson <mwh21 at cam.ac.uk> wrote:
> > jhefferon at my-deja.com writes:
> >
> > > I have a class, rclass.  It has an attribute value.  Can I arrange
> > > so that the string
> > >     r1=r2
> > > sets r1.value to equal r2.value (where r1 and r2 are class
> instances,
> > > of course) without changing anything else about r1?
> >
> > No. Assignment rebinds references, rather than affecting objects. This
> > is quite a difference from C++ (say), probably one of the harder ones
> > to get one's head around.
> >
> > >
> > > And if so, can I also have r1=7 set r1.value to be 7?
> > >
> > Hmm... do you know about the "exec <blah> in globals,locals" style of
> > doing things? Though `exec'ing user input sounds deeply unwise to me.
> > What is it you are trying to do? Maybe we can come up with a better
> > solution (no promises though).
> 
> Thanks.  I *am* reluctant to allow students to accidently exec something
> that erases all files, or something.

Accident? The least of your worries, I'd say!

> I am simulating a computer.  It is made up of registers and each
> register (memory or CPU) may have more than one attribute (for instance,
> whether to print it out in binary or hex, or how many times it has
> been referenced in this program, or what source line compiled to this
> register, etc.).  That's why each register is a class instance rather
> than a simple variable.
> 
> I want to have the obvious GUI, that allows a person to scroll through
> memory, for instance.  I also want to allow them to do things like
> set a register `rA=7' or `rA=memory[52]'.
> 
> In the register class I can use __setattr__ to let me write either
>   `rA.value=7' or `rA.value=memory[52]',
> right (I look at the type of the thing on the right and if it is a
> class instance then I see if, say, memory[52].classtype==``register'')?
> But I can't eliminate the `.value' on the left?  I thought maybe I could
> mess with the top-level dictionary (I don't know what I mean by that!).

Try this:

def process_input(user_input,registers):
    """ process_input(user_input:String, registers:{String:Register}) -> None

Given the user input and a dictionary mapping register names to
Register objects, set the values of the registers to the appropriate
values."""

    ourdict = {}
   
    for k,v in registers: 
        ourdict[k] = v.value
    
    # no naughties! (prevents file access/imports)
    ourdict["__builtins__"] = {}
    
    ourdict["memory"] = global_memory_object # or whatever

    exec user_input in ourdict

    for k,v in ourdict:
        if registers.has_key(k):
             registers[k].value = v

Is that helpful?

The basic idea is to control *really* tightly what the code can access
when `exec'ed - the __builtins__ issue is really quite subtle, but
helpful to know about.

There's rexec if you want the code to have more structured access to
other things.

I don't *think* it's possible to worm malicious effects through the
above code, but I might be wrong - any takers?

Cheers,
Michael



More information about the Python-list mailing list