2015-01-12 3 views
0

У меня есть некоторые данные, хранящиеся в объекте Foo().автоматическое определение новых функций в python

Foo.data - это список n x m np.array, где каждый массив представляет собой экспериментальные данные в определенное время. Массив состоит из m переменных, а n соответствует числу различных точек, в которых было выполнено измерение.

Мы можем считать, что мы имеем в нашем распоряжении список названия переменных, например:

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

Я хочу хотел бы сделать более доступными данные, определяя что-то вроде:

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] 

Вопрос заключается в следующем: учитывая, что список переменных не является фиксированным, но он может меняться, могу ли я автоматически определить некоторые функции, которые выполняют то, что я показываю ранее, без явного определения одного для каждой переменной?

Я имею в виду, я хотел бы иметь кучу функций, таких как Foo.P, Foo.volume, Foo.u, Foo.rho, которые извлекают значение переменной, заданное именем функции, для a (x, time), не определяя их все по одному.

+0

Вы можете использовать 'GetAttr()': http://stackoverflow.com/q/4075190/882697 – Plouff

+0

Посмотрите на ['namedtuple'] (https://docs.python.org/2/library/collections.html#collections.namedtuple). –

+0

Если мой ответ помогает, не забудьте принять его. :) –

ответ

1

Почему бы вам просто не передать имя? Как это:

#!/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) 
+0

Да, это была моя первоначальная идея, но я искал что-то «выглядящее лучше» (т. Е. Вызывал непосредственно имя переменной), и тогда вопрос казался мне интересным. – Pierpaolo

+0

@ thunder1123 Тогда вам придется использовать лямбда и getattr. Но, с моей точки зрения, они одинаковы. лямбда-часть - общая часть. Между тем, лямбда сделает код не столь удобочитаемым. –

2

Вы можете сделать это, определив особый __getattr__ метод на Foo, как это:

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)] 
+0

Почему вы использовали лямбда? – Pierpaolo

+0

Ну, эта функция должна вернуть функцию, поэтому лямбда казалась достаточно естественной. Конечно, есть несколько способов сделать это. –

+0

Как изменить функцию для поддержки вызовов типа Foo.P (x, time). Потому что сейчас это не работает. – Pierpaolo

Смежные вопросы