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?
3 Answers 3
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.
5 Comments
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)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!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")
Comments
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.