【发布时间】:2023-01-30 20:59:53
【问题描述】:
我一直在浏览有关动态属性设置的所有 Stackoverflow 答案,但无论出于何种原因,我似乎无法让它发挥作用。
我有一个类,Evolution_Base,它在它的init 中创建了一个Value_Differences 的实例。 Value_Differences 应该根据我传递的列表动态创建 properties,它从 _get_df_change 返回函数值:
from pandas import DataFrame
from dataclasses import dataclass
import pandas as pd
class Evolution_Base():
def __init__(self, res_date_0 : DataFrame , res_date_1 : DataFrame):
@dataclass
class Results_Data():
res_date_0_df : DataFrame
res_date_1_df : DataFrame
self.res = Results_Data(res_date_0_df= res_date_0,
res_date_1_df= res_date_1)
property_list = ['abc', 'xyz']
self.difference = Value_Differences(parent = self, property_list=property_list)
# Shared Functions
def _get_df_change(self, df_name, operator = '-'):
df_0 = getattr(self.res.res_date_0_df, df_name.lower())
df_1 = getattr(self.res.res_date_1_df, df_name.lower())
return self._df_change(df_1, df_0, operator=operator)
def _df_change(self, df_1 : pd.DataFrame, df_0 : pd.DataFrame, operator = '-') -> pd.DataFrame:
"""
Returns df_1 <operator | default = -> df_0
"""
# is_numeric mask
m_1 = df_1.select_dtypes('number')
m_0 = df_0.select_dtypes('number')
def label_me(x):
x.columns = ['t_1', 't_0']
return x
if operator == '-':
return label_me(df_1[m_1] - df_0[m_0])
elif operator == '+':
return label_me(df_1[m_1] + df_0[m_0])
class Value_Differences():
def __init__(self, parent : Evolution_Base, property_list = []):
self._parent = parent
for name in property_list:
def func(self, prop_name):
return self._parent._get_df_change(name)
# I've tried the following...
setattr(self, name, property(fget = lambda cls_self: func(cls_self, name)))
setattr(self, name, property(func(self, name)))
setattr(self, name, property(func))
它让我发疯......任何帮助表示赞赏!
我想要的结果是:
evolution = Evolution_Base(df_1, df_2)
evolution.difference.abc == evolution._df_change('abc')
evolution.difference.xyz == evolution._df_change('xyz')
编辑:这个简单的问题真的是,我如何为一个属性设置属性功能?
【问题讨论】:
-
没有理由为
Evolution_Base的每个实例重新定义Results_Data:只需全局定义它。 -
显示预期的输入 (df_1, df_2) 和输出。
-
有点旁注,但我怀疑您是否真的想将
property_list = []指定为 mutable default argument。也许你的意思是property_list: list? -
我不知道你的用例,所以这可能是一个愚蠢的问题,但是你没有在
Value_Difference上定义找零方法的原因是什么,如果这是你想要访问它的路线?如果它是您使用Value_Difference的主要目的,并且您不想继续键入方法名称,您甚至可以将其定义为__call__。那么它就像evolution.difference('xyz')一样简单。 -
@keynesiancross 你能解释一下你为什么要这样做吗?在我看来,使用 python 动态设置类的属性会给代码库带来很多维护问题,如果你想这样做,我真的会考虑重新考虑。例如,您可以创建所有可能的属性(假设它是一个已定义的列表),并使它们返回
None或其他一些无差异指示。它还将为那些与此类交互的人创建一个更清晰的 api,因此他们将来不可能获得AttributeErrors
标签: python