MarkoBox
MarkoBox

Reputation: 95

Passing method name as function argument

I'm probably missing something obvious here, what I'm trying to do is extract part of this Django view into a function since I'm using same code multiple times:

def method_name(pk, method_name, model_name):
    instance = get_object_or_404(Document, id=pk)
    wb = instance.method_name()
    with NamedTemporaryFile() as tmp:
        wb.save(tmp.name)
        tmp.seek(0)
        stream = tmp.read()
    instance.model_name.save('POPDV.xlsx', ContentFile(stream), save=False)
    instance.save()

I would like to pass model_name as a method name (in bold). What is the correct way to do this? My solution would be calling instance.__getattribute__ ("model_name").save(...)

Upvotes: 0

Views: 59

Answers (1)

user2390182
user2390182

Reputation: 73470

You can use getattr to access attributes by name:

wb = getattr(instance, method_name)()
# ...
getattr(instance, model_name).save(...)

getattr(obj, name) implicitly goes through the various attribute lookup options: obj.__getattribute__(name), obj.__dict__['name'], obj.__getattr__(name)

Usually, you do not call magic methods directly. They often are hooks for built-in methods or operators, e.g. iter(obj) calls obj.__iter__(), len(obj) calls obj.__len__().

Upvotes: 4

Related Questions