Reputation: 2544
I'm looking to pass a class and it's methods into a class. I have no problem with passing the class as it's accessible during instance initiation but the methods (when passed separately) are not.
The non-functional example is simplified a lot and only the classes Caller and Callable could be modified, the initial call should remain unmodified. I would prefer to not go with exec or eval if at all possible.
class Caller(object):
def __init__(self, **kwargs):
super(Caller, self).__init__()
self.klass = kwargs.get('klass', None)
self.func = kwargs.get('func', None)
self.klassParams = kwargs.get('klassParams', None)
def call(self):
klass = self.klass(**self.klassParams)
# Call the function
someFunc = self.func
klass.someFunc()
class Callable(object):
def __init__(self, **kwargs):
super(Callable, self).__init__()
def someFunction():
pass
c = Caller(klass=Callable, func=someFunction, klassParams={'some':'param'})
c.call()
This will obviously fail with NameError: name 'someFunction' is not defined
Upvotes: 1
Views: 60
Reputation: 71689
You can use the getattr
bulit in function in python, here is how you can use it,
Return the value of the named attribute of object. name must be a string. If the string is the name of one of the object’s attributes, the result is the value of that attribute. For example, getattr(x, 'foobar') is equivalent to x.foobar. If the named attribute does not exist, default is returned if provided, otherwise AttributeError is raised.
I have made quite a few corrections to your code, so now the code will work fine,
class Caller(object):
def __init__(self, parent=None, **kwargs):
# Calling object class constructor doesn't take the argument name parent as its the base class in python
super(Caller, self).__init__()
self.klass = kwargs.get('klass', None)
self.func = kwargs.get('func', None)
self.klassParams = kwargs.get('klassParams', None)
def call(self):
klass = self.klass(**self.klassParams)
# Call the function
someFunc = self.func
getattr(klass, someFunc)()
class Callable(object):
def __init__(self, some=None, parent=None):
# Calling object class constructor doesn't take the argument name parent as its the base class in python
super(Callable, self).__init__()
def someFunction(self):
print("someFunction called by Caller")
pass
# You have to pass the string representating the name of function to be called, in this case pass `'someFunction'`
c = Caller(klass=Callable, func='someFunction', klassParams={'some':'param'})
c.call()
The output will be,
someFunction called by Caller
Upvotes: 1