generate methods at runtime, but the wrong one gets called

Maric Michaud maric at aristote.info
Mon Aug 25 06:52:44 EDT 2008


Le Monday 25 August 2008 11:37:23 Steven Samuel Cole, vous avez écrit :
> Hello,
>
> I am writing an application that controls robots. Different robots can
> do different kinds of movements, such as e.g. open gripper, rotate
> gripper, etc. My RobotControl class should support all kinds of
> robots. I therefore delegate the actual control work to extra
> control-specific classes, one class per movement type, e.g.
> OpenGripperControl, RotateGripperControl. These movement control
> classes are created by a simple class factory.
>

i don't get your design, it seems over-complicated to mee at first glance.

> This is my class half-way through:
...
>
> I tried this in class RobotControl in __init__() in the 'for
> movementType ...' loop:
>
>     funcName = 'Set' + movementType
>     function = lambda self, value:
> self.__setMovementTypeValue(movementType, value)
>     method   = new.instancemethod(function, self, self.__class__)
>     setattr(self, funcName, method)
>
> and the code somewhat seems to work, but instead of SetOpenGripper,
> SetRotateGripper is called.
>

The free variable movementType in the lambda is evaluated lately as it were in 
its last state once you return from __init__, if you want to early bind it to 
its value in each step of a for loop, you must use :

func = lambda s, v, m_t=movementType : s.__setMovementTypeValue(m_t, v)

> My questions:
>
> 1.) Does this look like a somewhat reasonable approach to someone who
> knows more about Python than me ?

At first, what you do is creating instancemethod and bound them to an instance 
of your class, I find this confusing. Why not just use __getattr__ special 
method ?

(you don't need __setMovementTypeValue in this example)

def __getattr__(self, name) :
    if name.startswith('Set') :
        movement = name.lstrip('Set')
        if movement in self.__controls :
            return lambda value : self.__controls[movement].SetValue(value)
    raise AttributeError

That said, if I understand you well, your class RobotControl seems to contain 
only logic that is not specific to an instance, nor to a class of instances. 
In other OOP language I would encourage you to implement this logic in some 
sort of singleton, but in python we don't like this construct, module level 
variables and function do perfectly the job, simple as they are.

> 2.) What could I be doing wrong ?
>
> I have a suspicion that my error is not even related to all this fancy
> runtime code generation stuff, but something really dumb and I've just
> been coding for too long to see it.
>
> http://mail.python.org/pipermail/python-list/2007-June/446601.html
> shows a somewhat comparable constellation and it was a good guideline.
> But there, the function is created by the class factory, as well and I
> unfortunately can't do that.
>
> Thank you very much,
>
> Steve
> --
> http://mail.python.org/mailman/listinfo/python-list



-- 
_____________

Maric Michaud



More information about the Python-list mailing list