1

I want to have a class with dynamic methods.

From these arrays:

prefix = ['android','iphone','blackberry'] 
method = ['AddToPush','DelFromPush','GetPushMessages']

I want to create a class like:

class MobileManager(object)
 def __init__(self):
 self.mobileLib = MobileLib()
 def androidAddToPush(self, args):
 self.mobileLib.AddToPush(args, 'android')
 def iphoneAddToPush(self, args):
 self.mobileLib.AddToPush(args, 'iphone') 
 def blackberryAddToPush(self, args):
 self.mobileLib.AddToPush(args, 'blackberry') 
 [...]

How can I have these methods generated/created at runtime?

UpAndAdam
5,5165 gold badges33 silver badges49 bronze badges
asked Dec 30, 2011 at 9:05

3 Answers 3

1

If your set of prefixes/methods is defined at init time, you can try something like this:

class MobileManager(object):
 def __init__(self):
 for prefix_name in prefix:
 for method_name in method:
 func = lambda self, args: getattr(self.mobileLib, method_name)(args, prefix)
 full_method_name = "%s%s" % (prefix, method_name)
 setattr(self, full_method_name, func)
 ...

If your dynamic methods get more complicated, the lambda will soon be limited, though.

answered Dec 30, 2011 at 9:11
Sign up to request clarification or add additional context in comments.

5 Comments

Will it work like this: self.mobileLib.method_name(args, prefix) ?
In Your code You have line: func = lambda self, args: self.mobileLib.AddToPush(args, prefix) 'AddToPush' should be from method array.
It won't work: 1. drop self from func() parameters (you bind it to a concrete instance, not a class). 2. all func will use the last value of method_name. You don't want that.
setattr(self, prefix+method_name, make_func(getattr(self.mobileLib, method_name), prefix)) should fix it, where make_func = lambda func, prefix: lambda args: func(args, prefix)
This one is working! make_func = lambda func, prefix_name: lambda args: func(args, prefix_name) setattr(self, prefix_name+method_name, make_func(getattr(self.mobileLib, method_name), prefix_name)) Thanks a lot!
0

Or why not inherate

class MobileManager(object)
 def __init__(self):
 self.mobileLib = MobileLib()
 def AddToPush(self, args, platform=None):
 self.mobileLib.AddToPush(args, platform)
class Android(MobileManager):
 def __init__(self):
 MobileManager.__init__(self)
 def AddToPush(self, args):
 MobileManager.AddToPush(args, platform="android")
answered Dec 30, 2011 at 11:39

Comments

0

Dynamic methods are often the wrong approach leading to confusing code.

Here, I'd do this:

class Mobile(object):
 def add_to_push(self, args):
 ....
 def del_from_push(self, args):
 ...
 def get_push_methods(self, args):
 ...

And in your Manager:

class MobileManager(object):
 def __init__(self):
 self.android = Mobile()
 self.blackberry = Mobile()
 self.iphone = Mobile()

Now, instead of manager.mobileLib.add_to_push(args, 'android'), you would write manager.android.add_to_push(args).

You can even dispatch dynamically if you have a platform variable: getattr(manager, platform).add_to_push(args).

If you want different behaviour for the 3 types of platform you can make subclasses of Mobile (perhaps AndroidMobile, BlackberryMobile and IPhoneMobile).

When a new platform appears (perhaps windows7) it's obvious how to change the code to support it.

answered Dec 30, 2011 at 11:57

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.