2017-02-22 98 views
1

Я определил подкласс NewDataStructure, который наследуется от другого класса. Методы, действующие на самом объекте, отлично работают с этим подклассом. Однако методы, которые создают копию, возвращают объект родительского класса, а не подкласс. Это вызывает много проблем, когда я вызываю этот метод в других методах.Как я могу получить подкласс, чтобы вернуть копию самого себя, а не родительский класс, из которого он наследуется?

Есть ли способ указать, что именованный метод родительского класса должен возвращать объект подкласса?

Есть ли способ проинструктировать, что все унаследованные методы должны возвращать объект подкласса, а не родительский класс?

Возможно, я смог передать возвращенный объект функции __init__ моего класса? Мне нужно было бы изменить мой __init__ соответственно ... Что такое Pythonic?

import pandas as pd 


class NewDataStructure(pd.DataFrame): 
    def __init__(self, data, index, title): 
     super(NewDataStructure, self).__init__(data=data, index=index) 
     self.title = title 


new_data_variable = NewDataStructure(data=None, index=None, title="") 

changed = new_data_variable.unstack() 

new_data_variable.reset_index(inplace=True) 
unchanged = new_data_variable 

print type(changed) 
print type(unchanged) 

<class 'pandas.core.series.Series'> 
<class '__main__.NewDataStructure'> 

ответ

7

Я боюсь, что ваш вопрос классический XY question, вы спрашиваете, как сделать Y, который, по вашему мнению, является решением проблемы X, тогда как на самом деле это не отличное решение для X, и, вероятно, лучший подход будет заключаться в том, чтобы попробуйте другое решение для X.

X примерно «как связать дополнительную функциональность с DataFrame?», а как указано в @ppkt, это обсуждается в this question. Основная проблема с указанным выше подклассом - это тот, который вы нажимаете, что у класса есть фабричные методы, которые производят новые экземпляры класса, но это не то, что вы обычно можете легко манипулировать из подкласса.

Однако, глядя на код pandas, вы можете использовать хак. DataFrame class defines a _constructor property:

class DataFrame(NDFrame): 
    ... 
    @property 
    def _constructor(self): 
     return DataFrame 

Который, кажется, используется для создания экземпляров, а не только DataFrame. Таким образом, вы можете быть в состоянии решить вашу проблему путем переопределения этого имущества на подкласса:

class NewDataStructure(pd.DataFrame): 
    ... 
    @property 
    def _constructor(self): 
     return NewDataStructure 

Это признанный образец откладывая создание экземпляра к способу/конструктора на заводе, который может быть изменен пользователем. Подобно способности модуля регистрации установить класс журнала с помощью logging.setLoggerClass().

Но это недокументированное дело, насколько я могу судить, поэтому вы делаете это на свой страх и риск. Даже если это сработает, вам, вероятно, будет лучше в долгосрочной перспективе больше узнать о композиции и наследовании и попробовать составное решение.

0

!!! Я на маленьком смартфоне !!!

В том виде, в котором вы используете код, вы используете повторяющийся вызов функции.

Насколько я могу вам сказать, что вы создали объект new_variable_data, но у вас нет функций, разработанных должным образом, что вы вызываете, если они не являются частью панд, и если это так, вам нужно будет создать для pd каждый раз и переназначить.

Что касается данных в качестве аргумента, переданных без него, вы бы хотели включить в него также оператор if, а затем назначить данные как объект для себя.

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

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