I need to use setattr to read from a configuration file, and set an attribute of a class to a function in another module. Roughly, here's the issue.
This works:
class MyClass:
def __init__(self):
self.number_cruncher = anothermodule.some_function
# method works like this, of course;
foo = MyClass()
foo.number_cruncher(inputs)
Ok, this is trivial, but what if I want to read the name of some_function from a configuration file? Reading the file and using setattr is also simple:
def read_ini(target):
# file reading/parsing stuff here, so we effectively do:
setattr(target, 'number_cruncher', 'anothermodule.some_function')
bar = MyClass()
read_ini(bar)
bar.number_cruncher(inputs)
This gives me a 'str' object is not callable error. If I understand correctly, it is because in the first case I'm setting the attribute as a reference to the other module, but in the second case it is simply setting the attribute as a string.
Questions: 1) is my understanding of this error correct? 2) How can I use setattr to set the attribute to be a reference to the function rather than simply a string attribute?
I've looked at other questions and found similar questions, but nothing that seemed to address this exactly.
anothermodule.some_functionis read from a file? If so, you are looking to use dynamic importing, andgetattr()on the resulting module object to resolve that string into the function object.anothermodule.some_functionis static (known at the time you write your code), then just useetattr(target, 'number_cruncher', anothermodule.some_function). That third argument doesn't have to be a string, it is the actual object you want to use as the value for the attribute you are setting.setattris the value that you set, so if that is a string you set a string. If it's an int it will be an int etc and then ofc an object for an object.