Re: generate methods at runtime, but the wrong one gets called

2008-08-26 Thread Bruno Desthuilliers

Maric Michaud a écrit :
(snip)

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



aol /
--
http://mail.python.org/mailman/listinfo/python-list


generate methods at runtime, but the wrong one gets called

2008-08-25 Thread Steven Samuel Cole
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.

This is my class half-way through:

class RobotControl:

def __init__(self, movementTypes):
self.__controls = {}
motionControlFactory = MotionControlFactory()
for movementType in movementTypes:
self.__controls[movementType] =
motionControlFactory.create(movementType)

def __setMovementTypeValue(self, movementType, value):
control = self.__controls[movementType]
control.SetValue(value)

# I want to provide methods like these to the client app,
# but without typing them explicitely:
def SetOpenGripper(self, value):
self.__setMovementTypeValue('OpenGripper', value)

def SetRotateGripper(self, value):
self.__setMovementTypeValue('RotateGripper', value)


My application:

movementTypes = ['OpenGripper', 'RotateGripper']
robotCtrl = RobotControl(movementTypes)
robotCtrl.SetOpenGripper(1.0)
robotCtrl.SetRotateGripper(2.0)


While control object creation is abstracted out into the class
factory, SetOpenGripper(...) and SetRotateGripper(...) are still in
there and I obviously want to get rid of them, at least in their
explicitely implemented form. Instead, I want to generate them at
runtime, depending on what movement types are required.

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.

My questions:

1.) Does this look like a somewhat reasonable approach to someone who
knows more about Python than me ?
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


Re: generate methods at runtime, but the wrong one gets called

2008-08-25 Thread Maric Michaud
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
--
http://mail.python.org/mailman/listinfo/python-list


Re: generate methods at runtime, but the wrong one gets called

2008-08-25 Thread Marc 'BlackJack' Rintsch
On Mon, 25 Aug 2008 12:52:44 +0200, Maric Michaud wrote:

 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.

Modules are some sort of singletons in Python.

Ciao,
Marc 'BlackJack' Rintsch
--
http://mail.python.org/mailman/listinfo/python-list