0

I have some data stored in a object Foo().

Foo.data is a list of n x m np.array, where each array represent some experimental data at a specific time. The array is composed by m variables, and n correspond to the number of different point where measurement has been taken.

We can consider that we have at our disposal a list of variables name, e.g:

var_names=['x','volume','u','L_bar','rho','P',.....]

I want like to make data more accessible, defining something like:

def Foo.P(self,x,time)
    index_t=time_list.index(time)
    index_x=var_names.index(x)
    index_P=var_names.index(P)
    return Foo.data[index_t][index_x,index_P]

The question is: considering that the list of variables is not fixed,but it can vary, can I automatically define some functions that do what I show before without explicitly defining one for each variable?

I mean, I would like to have a bunch of function such as, Foo.P, Foo.volume, Foo.u, Foo.rho that extract the value of the variable given by the function name, for a (x,time) position, without defining all of them one by one.

2

2 Answers 2

2

You can do it by defining the special __getattr__ method on Foo, like this:

def __getattr__(self, name):
    """If name is known, return a function to get that data for given (x, time)."""
    if name not in var_names: # name not known
        raise AttributeError
    return lambda x, time: self.data[time_list.index(time)][var_names.index(x), var_names.index(name)]
Sign up to request clarification or add additional context in comments.

4 Comments

Why did you use the lambda?
Well, this function needs to return a function, so a lambda seemed natural enough. There's more than one way to do it, of course.
How can I modify the function to support calls like Foo.P(x,time). Because right now it doesn't work.
@thunder1123: as a general rule, "it doesn't work" is not an actionable statement. If you have a specific problem, tell us.
1

Why don't you just pass the name through? Like this:

#!/usr/bin/python
# -*- coding: utf-8 -*-


var_names=['x','volume','u','L_bar','rho','P']

def general_foo(self, name, x, time)
    index_t=time_list.index(time)
    index_x=var_names.index(x)
    index_P=var_names.index(name)
    return Foo.data[index_t][index_x,index_P]

for var in var_names:
    general_foo(var, x, time)

2 Comments

Yeah, that was my initial idea, but I was looking some something "looking better" (ie calling directly by the variable name), and then the question seemed (to me) interesting.
@thunder1123 Then you will have to use lambda and getattr. But from my point of view, they are the same. lambda part is the general part. Meanwhile, lambda will make code not so readable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.