Search code examples
pythonreflectionintrospection

Seeking a different way in using Reflection or Introspection in Python


I'm refactoring some code, and I thought I could use a bit of Reflection! So, I have this for now:

def f(self, clazz):
    [...]
    boolean = False
    if hasattr(clazz_instace, 'some_attribute'):
        setattr(clazz_instace, 'some_attribute', True)
        boolean = True

    if boolean:
        result = getattr(clazz_instace, 'another_method')(None, request=request)
        return result['objects']

    sorted_objects = getattr(clazz_instace, 'One_more_method')(request)
    result = getattr(clazz_instace, 'another_method')(sorted_objects, request=request)

    return [...]

My question is about the strings I used to indicate which method I'm searching for regarding to the clazz_instance. I'd like to know if there's another and very best way to do what I did (In a dinamic way to be specific)? I mean, intead of putting method's name like strings directly as I did, would be really nice if I could verify dinamically those methods, differently.

Could you give some nice ideas? How would you do it?

Thanks in advance!!!


Solution

  • An instance's method is nothing more than a function object stored in the instace's __dict__. This said, you are doing correct to find them, except that maybe, the class indeed has the attribute corresponding to your argument string, but is not a function, is just another type instead.

    If you depend on this, I recommend you refactor the instance's function looking code into a helper method:

    import types
    def instance_has_method(instance, name):
        try:
            attr = getattr(instance, name)
            return isinstance(attr, types.FunctionType)
        except AttributeError:
            return False
    

    Once you have this function, your code will be more concise because now you're sure that the attribute is indeed a function and can be callable.

    The code above checks if the attribute is a function. If you want something wider, you can check if it's a callable like this: return hasattr(attr, '__call__').

    In python, this is basically how you check for attributes inside classes. I don't think there's nothing wrong with your approach and not another more clever way to do reflection.

    Hope this helps!