How do I declare a class member function in another class?

Please support our Python advertiser: Programming Forums - DaniWeb Sister Site
Reply

Join Date: May 2006
Posts: 8
Reputation: jonamasa is an unknown quantity at this point 
Solved Threads: 1
jonamasa jonamasa is offline Offline
Newbie Poster

How do I declare a class member function in another class?

 
0
  #1
Sep 3rd, 2007
Hi,

I have a class SubDevice with a function action.
For each instance of SubDevice I want to define another action, so it's a parameter of SubDevice's class constructor.
Now some of the action functions need additional parameters, but that's normally not a problem because I can write something like
  1. sd1 = SubDevice(action=lambda: f1(param1, param2))
But how do I pass the instance of SubDevice as a parameter of the action function? I can't use self, because self refers to the class Device, where I instantiate SubDevice.

Thank you


Johannes Riecken
Reply With Quote Quick reply to this message  
Join Date: Mar 2006
Posts: 18
Reputation: sharma_vivek82 is an unknown quantity at this point 
Solved Threads: 0
sharma_vivek82 sharma_vivek82 is offline Offline
Newbie Poster

Re: How do I declare a class member function in another class?

 
0
  #2
Sep 3rd, 2007
the solution, i got from your problem as explained is to construct another class which inherit SubDevice. And this ll make you to call your function as your wish.
Best wishes,
Vivek Sharma
Zope/Python Developer
Reply With Quote Quick reply to this message  
Join Date: Jan 2006
Posts: 237
Reputation: katharnakh is an unknown quantity at this point 
Solved Threads: 33
katharnakh's Avatar
katharnakh katharnakh is offline Offline
Posting Whiz in Training

Re: How do I declare a class member function in another class?

 
0
  #3
Sep 3rd, 2007
Hi Johannes Riecken,

But how do I pass the instance of SubDevice as a parameter of the action function? I can't use self, because self refers to the class Device, where I instantiate SubDevice.
Could you please provide, class implementation structure, so that by looking at code we can help you.

BTW, i never used function as a class constructor argument. Sounds something interesting. I would surely want to look into. I would surely like to look at it.

kath.
Last edited by katharnakh; Sep 3rd, 2007 at 9:22 am.
Reply With Quote Quick reply to this message  
Join Date: Jul 2006
Posts: 608
Reputation: jrcagle is on a distinguished road 
Solved Threads: 150
jrcagle jrcagle is offline Offline
Practically a Master Poster

Re: How do I declare a class member function in another class?

 
0
  #4
Sep 3rd, 2007
If I understand, you want something like this:

  1. class SubDevice(object):
  2.  
  3. def __init__(self, action):
  4.  
  5. self.action = action
  6.  
  7. def action1():
  8. print "Hello!"
  9.  
  10. def action2():
  11. print "Goodbye!"
  12.  
  13.  
  14. sd1 = SubDevice(action1)
  15. sd2 = SubDevice(action2)
  16.  
  17. sd1.action()
  18. sd2.action()
  19.  
  20. >>>
  21. Hello!
  22. Goodbye!

Now, I'm not sure where the variable parameter list would come into play. It seems to me that if you want a transparent interface, then you have to make the parameter list consistent. Can you give an example of what you had in mind?

Hope it helps,
Jeff
Reply With Quote Quick reply to this message  
Join Date: May 2006
Posts: 8
Reputation: jonamasa is an unknown quantity at this point 
Solved Threads: 1
jonamasa jonamasa is offline Offline
Newbie Poster

Re: How do I declare a class member function in another class?

 
0
  #5
Sep 4th, 2007
Hi,
As Sharma said one solution would be to construct subclasses of SubDevice for every different action and I thought about doing that in the beginning. However, my instructor is against it. Of course he's more procedurally oriented than younger programmers, but I agree that it would be too much overhead to construct subclasses, as they would be too specialized and they don't need any additional parameters.

Actually what jrcagle wrote is pretty much what I have in mind:
  1. class SubDevice(object):
  2.  
  3. def __init__(self, action, super_device):
  4.  
  5. self.action = action
  6. self.state = "ready"
  7. self.super_device = super_device
  8.  
  9. def action1():
  10.  
  11. if super_device.plate_count > 0:
  12. super_device.plate_count -= 1
  13.  
  14. else:
  15. XXX.state = "error"
  16.  
  17. def action2():
  18.  
  19. print "Goodbye!"
  20.  
  21. class SuperDevice(object):
  22.  
  23. def __init__(self, ...):
  24.  
  25. self.plate_count = 100
SuperDevice is larger device consisting of many different SubDevices. There could be numerous events when the plate_count has to decrease, so I have a separate method for it.
Now the problem is that I can't set the state field of SubDevice with action1, as I don't know what to replace XXX with.

Hope this helps!

Johannes
Last edited by jonamasa; Sep 4th, 2007 at 4:04 am.
Reply With Quote Quick reply to this message  
Join Date: Jan 2006
Posts: 237
Reputation: katharnakh is an unknown quantity at this point 
Solved Threads: 33
katharnakh's Avatar
katharnakh katharnakh is offline Offline
Posting Whiz in Training

Re: How do I declare a class member function in another class?

 
0
  #6
Sep 4th, 2007
Hi,

I am not sure i understand your problem. I have some questions before i say something.
  1. def action1():
  2.  
  3. if super_device.plate_count > 0:
  4. super_device.plate_count -= 1
  5.  
  6. else:
  7. XXX.state = "error"

in the above code, is super_device object of SuperDevice class and is global?

If I believe it is,
Now the problem is that I can't set the state field of SubDevice with action1, as I don't know what to replace XXX with.
you can return "error" so that SubDevice which is calling that action function will get the state value.


let me know how this works...


kath.
Last edited by katharnakh; Sep 4th, 2007 at 4:39 am.
Reply With Quote Quick reply to this message  
Join Date: May 2007
Posts: 15
Reputation: ffao is an unknown quantity at this point 
Solved Threads: 4
ffao ffao is offline Offline
Newbie Poster

Re: How do I declare a class member function in another class?

 
0
  #7
Sep 11th, 2007
Is there any problem in making the self argument in the action functions mandatory?

  1. import functools
  2. class SubDevice(object):
  3. def __init__(self, action):
  4. #always pass a reference to self as first argument
  5. self.action = functools.partial(action, self)
  6. self.state = "ready"
  7.  
  8. def action1(self): #the argument list has to contain self!
  9. if self.state == "ready":
  10. self.state = "error"
  11. else:
  12. self.state = "ready"
  13.  
  14. a = SubDevice(action1)
  15. a.action()
  16. print a.state # 'error'
Last edited by ffao; Sep 11th, 2007 at 9:41 pm.
Reply With Quote Quick reply to this message  
Join Date: Jul 2006
Posts: 608
Reputation: jrcagle is on a distinguished road 
Solved Threads: 150
jrcagle jrcagle is offline Offline
Practically a Master Poster

Re: How do I declare a class member function in another class?

 
0
  #8
Sep 11th, 2007
Huh. There's something funky here that I don't understand. Because I don't have the module functools, I simplified a bit:

  1. class SubDevice(object):
  2. def __init__(self, action):
  3. #always pass a reference to self as first argument
  4. self.action = action # functools.partial(action, self)
  5. self.state = "ready"
  6.  
  7. def action1(self): #the argument list has to contain self!
  8. if self.state == "ready":
  9. self.state = "error"
  10. else:
  11. self.state = "ready"
  12.  
  13. a = SubDevice(action1)
  14. a.action() #### <---
  15. print a.state # 'error'

Shockingly, this throws an error:

  1. Traceback (most recent call last):
  2. File "C:/Python24/subdevicetest.py", line 14, in -toplevel-
  3. a.action()
  4. TypeError: action1() takes exactly 1 argument (0 given)

Now, my understanding of the paradigm was that a.action() called the member method with a as the first parameter. Yet ... it doesn't!

When I replace with:

  1. class SubDevice(object):
  2. def __init__(self, action):
  3. #always pass a reference to self as first argument
  4. self.action = action # functools.partial(action, self)
  5. self.state = "ready"
  6.  
  7. def action1(self): #the argument list has to contain self!
  8. if self.state == "ready":
  9. self.state = "error"
  10. else:
  11. self.state = "ready"
  12.  
  13. a = SubDevice(action1)
  14. a.action(a) ### <----
  15. print a.state # 'error'

Then it works fine. So yes, I think there is an issue with what you want to do, and no, I don't (yet) know what it is.

Vega, thoughts?

Jeff
Reply With Quote Quick reply to this message  
Join Date: Jul 2006
Posts: 608
Reputation: jrcagle is on a distinguished road 
Solved Threads: 150
jrcagle jrcagle is offline Offline
Practically a Master Poster

Re: How do I declare a class member function in another class?

 
0
  #9
Sep 11th, 2007
Followup -- here's a quote from Yoda himself:

Originally Posted by Guido vR
What exactly happens when a method is called? You may have noticed that x.f() was called without an argument above, even though the function definition for f specified an argument. What happened to the argument? Surely Python raises an exception when a function that requires an argument is called without any--even if the argument isn't actually used ...
Actually, you may have guessed the answer: the special thing about methods is that the object is passed as the first argument of the function. In our example, the call x.f() is exactly equivalent to MyClass.f(x). In general, calling a method with a list of n arguments is equivalent to calling the corresponding function with an argument list that is created by inserting the method's object before the first argument.
So Guido thinks your code oughta work. Something funky is going on here. Or I'm not thinking straight. LOL

BTW, the clean way to do what you want is this:

  1. class SubDevice(object):
  2. def __init__(self, action):
  3. #always pass a reference to self as first argument
  4. self.action = lambda : action(self)
  5. self.state = "ready"
  6.  
  7. def action1(self): #the argument list has to contain self!
  8. if self.state == "ready":
  9. self.state = "error"
  10. else:
  11. self.state = "ready"
  12.  
  13. a = SubDevice(action1)
  14. a.action()
  15. print a.state # 'error'


Jeff
Last edited by jrcagle; Sep 11th, 2007 at 10:24 pm. Reason: thought
Reply With Quote Quick reply to this message  
Join Date: Jul 2006
Posts: 608
Reputation: jrcagle is on a distinguished road 
Solved Threads: 150
jrcagle jrcagle is offline Offline
Practically a Master Poster

Re: How do I declare a class member function in another class?

 
0
  #10
Sep 11th, 2007
Ah. Many regards to Matthew Dixon Cowles over at Python-help, who says,

Originally Posted by MDC
Dear Jeff,
> Hi,
Hello!
> I was trying to assist someone who wants to hook methods into
> objects post-instantiation.
> I'm really confused. I thought that a.action() automatically
> passed a as the first parameter.
You can stick a Python function pretty much anywhere:
>>> def f():
... print "wibble"
...
>>> l=[f]
>>> l[0]()
wibble

But making a function an attribute of an object doesn't automatically
make it a method:
>>> class c:
... pass
...
>>> o=c()
>>> o.x=f
>>> o.x()
wibble

There, f is a plain function that's an attribute.

To make a function into an instance's method, you need the
instancemethod() function of the new module:
>>> def m(self):
... print "wibble"
...
>>> import new
>>> o.m=new.instancemethod(m,o,c)
>>> o.m()
wibble

Regards,
Matt
There it is. Following this lead, your code could become:

  1. import new
  2.  
  3. class SubDevice(object):
  4. def __init__(self, action):
  5. #always pass a reference to self as first argument
  6. self.action = new.instancemethod(action,self,SubDevice)
  7. self.state = "ready"
  8.  
  9. def action1(self): #the argument list has to contain self!
  10. if self.state == "ready":
  11. self.state = "error"
  12. else:
  13. self.state = "ready"
  14.  
  15. a = SubDevice(action1)
  16. a.action()
  17. print a.state # 'error'

and that works.

I would not have predicted that... LOL

Jeff
Reply With Quote Quick reply to this message  
Reply

This thread is more than three months old.
Perhaps start a new thread instead?
Message:




Views: 3435 | Replies: 9
Thread Tools Search this Thread



Tag cloud for Python
About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC