Search code examples
pythonclassobjectgetattr

Parsing Object Attribute with an Input Value


I'm starting to think this is something that may not be doable in Python in an easy way. Either that or I cannot seem to word this question well enough for Google to solve it (or to find a StackOverflow answer of it).

Here is some lite code to help carry the explanation along:

import numpy as np
class MyObject():
    def __getattr__(self, item):
            return getattr(np.eye(1), item)

This simple setup makes sure that I get a numpy array (with just the value 1 in it) back whenever I call to an attribute. This allows me to make calls to the numpy array functions, such as MyObject.sum() which returns an integer value ultimately.

There are also other functions which require input such as: MyObject.dot(AnotherNumPyArray)

So far so good... but, I want to have a special function take place when the output value is not strictly an integer. i.e. in the second case where I get a ndarray as the output.

My attempt at partially solving this:

import numpy as np
class MyObject():
    def __getattr__(self, item):
            func = getattr(np.eye(1), item)
            if type(func()) == np.ndarray:
                return func()*2
            else:
                return func

The only problem is that this works only if there are no input parameters to the function getting called out. I feel like I want to run func(value) in the if-statement but, 1) I do not know how to pass in the value. And 2) once returning from __getattr__ then that value would attempt get parsed a 2nd time.


Solution

  • You could return a wrapped method, for example:

    import numpy as np
    
    class MyObject():
    
        def __getattr__(self, item):
            def wrapper(*args, **kwargs):
                func = getattr(np.ndarray(1), item)
                result = func(*args, **kwargs)
                if isinstance(result, np.ndarray):
                    return result * 2
                return result
            return wrapper
    

    Here wrapper delegates the incoming call to the method on np.ndarray(1), and handles the returned result as appropriate.