I am trying to invoke a method on a class dynamically using a String for the class name and a String for the method name. I am using getattr
then invoking a method on the class. You'll have to forgive me if I am way off, I am kind of new to Python.
class mock:
def __init__(self):
pass
def create(self):
print('hello world?')
return 'hello world'
then creating the instance and invoking via :
module = importlib.import_module('xyz.module')
instance = getattr(module, 'mock')
invoke = getattr(instance, 'create')
result = invoke()
print(result)
The result is something like <object object at 0x10943ccd0>
. "hello world?" is never printed. What am I doing wrong?
CodePudding user response:
You have missed a step. The instance
variable you have isn't actually an instance, it's the class mock
itself. You need to call it to get an instance. Try something like this:
module = importlib.import_module('xyz.module')
klass = getattr(module, 'mock') # rename this variable (avoiding keywords)
instance = klass() # and call the class to create an instance
method = getattr(instance, 'create') # also renamed here, for clarity
result = method() # previously, this would have been an error (missing self argument)
print(result) # now you should get "hello world" printed twice (once with a ?)
As a note, PEP 8 naming conventions would have helped you avoid the issue here. If you'd used the name Mock
instead of mock
for the class, it might have been a bit more obvious what kind of thing you had, after importing and getattr
ing it.
CodePudding user response:
You don't need getattr
at all; the instance returned by import_module
is the same thing that would be implicitly bound to xyz.module
had you used an import
statement.
module = importlib.import_module('xyz.module')
result = module.mock().create()
assert result == "hello world"
Note that the above creates an instance of mock
on which to call create
, rather than accessing mock.create
directly. If you have variables containing the name of the class and the method, you still need to do that, only using getattr
this time.
module = importlib.import_module('xyz.module')
cls_name = 'mock'
method_name = 'create'
cls = getattr(module, 'mock')
instance = cls()
invoke = getattr(instance, 'create')
result = invoke()
assert result == "hello world"