Python: динамически создавать методы на основе других классов - PullRequest
0 голосов
/ 16 ноября 2011

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

Пока что у меня есть что-то подобное, кто-нибудь может меня направить?

Спасибо

Class A():

    def__init__(self,array):
        self.data = array

    def method1(self,*args):
        newarray = whatever(self.data,*args)
        return newarray

    def method2(self,*args):
        newarray = whatever2(self.data,*args)
        return newarray

Я хочу иметь возможность использовать эти методы для генерации новых в более сложном классе, скажем:

class B(C):    #inherits from C

    def __init__(self,[arg1,array]):
        #initialize from parent class
        C.__init__(self,[arg1,array])

        #create new methods for this class using same name
        methodnames = [element for element in dir(A) if element[0] != '_']

        for methodname in methodnames:
            ##following works but this is not the output I want here
            #self.__dict__[methodname] = getattr(A(array),methodname)

            #following doesn't work... at least not as I expect it to
            #case1
            #self.__dict__[methodname] = [arg1,getattr(A(array),methodname)]
            #case2
            self.__dict__[methodname] = list([arg1,getattr(A(array),methodname)])

a = array
#following returns a list of [arg1, method] but what I really want is [arg1,newarray]
C([arg1,array]).method1(*args)

ОК, так что давайте попробуем прояснить ситуацию:

Класс A содержит фильтры, принимает массив и применяет фильтр в качестве метода, возвращает отфильтрованные данные.

Фильтры класса ()

def__init__(self,array):
    self.data = array

def filter1(self,*args):
    newarray = median(self.data,*args)
    return newarray

def filter2(self,*args):
    newarray = gaussian(self.data,*args)
    return newarray

...

В другом модуле у меня есть класс SpecialData, который работает со списком данных x, y (где x и y - итерируемые, то есть списки, массивы ...). Так что-то вроде

Класс SpecialData ():

def __init__(self,[x,y]):
    self.data = [x,y]

def power(self,power):
    ypow = self.data[1]**power
    return [x,pow]

def porod(self):
    return [x**4,x**4*y]

....

Теперь я хочу добавить методы фильтра, содержащиеся в фильтрах класса, в класс SpecialData. Конечно, я мог бы сделать это, перекодировав все фильтры в надлежащем формате для SpecialClass. но я действительно хочу, чтобы каждый раз, когда к фильтрам классов добавлялся новый фильтр, чтобы он был доступен во время выполнения в классе SpecialData без необходимости повторного кодирования нового фильтра.

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

фильтры импорта

filternames = [элемент для элемента в dir (фильтры), если элемент [0]! = '_']

для fitlername в filternames: generate_filters_in_class_SpecialClass

Как мне сделать это правильно?

Я нашел несколько сообщений, связанных с этим, некоторые с использованием super (), другие с использованием SpecialData. dict или даже setattr. Поскольку второе мне показалось более понятным, я сосредоточился на этом и придумал:

фильтры импорта

Класс SpecialData ():

def __init__(self,[x,y]):
    self.data = [x,y]

    filternames = [element for element in dir(filters) if element[0] != '_']

    for fitlername in filternames:

        self.__dict__[fitlername ] = [self.data[0],getattr(filters(self.data[1]),fitlername)]

Конечно, это не работает, потому что список не вызывается. Если я изменю последнюю строку на: self. dict [fitlername] = список ([self.data [0], getattr (фильтры (self.data [1]), fitlername)]) он возвращает метод как 2-й элемент, а не результат.

Обратите внимание, что следующее работает, но это не то, что я хочу ... self. dict [fitlername] = getattr (filters (self.data [1]), fitlername)

Надеюсь, теперь все стало понятнее ...

Ответы [ 2 ]

1 голос
/ 16 ноября 2011

Я думаю, что вы пытаетесь использовать расширенный Python, не используя / не зная его расширенных возможностей, например, заимствуя методы у другого языка.

Это не критика, но вы должны взглянутьна Учебник Python , Самоанализ Python или метаклассы .

Я думаю, что если вы просто завершите свои знания по функциям Python Вы легко сможете решить свою проблему намного проще.

0 голосов
/ 16 ноября 2011

Вместо того, чтобы генерировать предлагаемое решение, вы должны прояснить, чего вы пытаетесь достичь.Класс А является ярким примером отправной точки;пожалуйста, опубликуйте пример желаемой конечной точки, например,

Class B(): 

    def__init__(self,array): 
        self.data = array 

    def method1(self,*args): 
        newarray = ComplexWhatever(self.data,*args) 
        return newarray 

    def method2(self,*args): 
        newarray = EvenBiggerWhatever2(self.data,*args) 
        return newarray 

a = A(input_array)
b = B(input_array)
print(a.method1(args))
print(b.method1(args))

Что не ясно, так это то, как вы хотите "динамически генерировать" новую функцию "ComplexWhothing ()" вместо написания функции вручную.

...