创建属性的属性-可能吗?

时间:2019-03-22 16:31:03

标签: python oop attributes

我正在处理许多不同数据集(例如,气温,海洋温度,风速等)的月度数据,因此每个月和每个数据集将共享相似的属性。我希望能够尽可能高效地初始化和填充这些属性。到目前为止,我只能想到尝试以某种方式将新属性附加到预先存在的属性中。在Python中有可能吗?

例如,假设我初始化了所有的每月变量,如下所示:

class Data_Read:
    def __init__(self, monthly=np.zeros((200,200,40))): #3D data
        self.jan = monthly 
        self.feb = monthly
        self.march = monthly
        self.april = monthly
        self.may = monthly
        self.june = monthly
        self.july = monthly
        self.august = monthly
        self.sept = monthly
        self.oct = monthly
        self.nov = monthly
        self.dec = monthly

然后,我可以为每个月创建一个新的数据集,方法如下:

air_temp.jan

这些将是原始数据属性。但是,我接下来想对这些数据集中的每个数据集进行一些处理(例如去趋势)。有没有一种方法可以创建一个类(或新类?),该类将生成诸如wind_speed.june之类的新属性。基本上,我希望避免为要创建的每个属性编写12行代码,然后在以后的数据处理函数中轻松调用任何“属性的属性”。

非常感谢。

1 个答案:

答案 0 :(得分:0)

这是一个示例,该示例说明了如何将所有内容内部存储在字典中,并且仍然将数组作为属性以及按名称对数组的调用函数进行引用:

import numpy as np


class Data_Read:
    def __init__(self, monthly_shape=(200, 200, 40)): #3D data
        months = [
            "jan",
            "feb",
            "march",
            "april",
            "may",
            "june",
            "july",
            "august",
            "sept",
            "oct",
            "nov",
            "dec"
        ]
        self._months = {month: np.zeros(monthly_shape) for month in months}

    def detrend(self, month):
        # this is a dummy function that just increments
        return self._months[month] + 1

    def __getattr__(self, name):
        if name in self._months:
            return self._months[name]
        return super().__getattr__(name)

air_temp = Data_Read()
print(air_temp.jan.shape)  # (200, 200, 40)
print((air_temp.detrend("jan") == 1).all())  # True

您还可以使用setattrgetattr获得相同的结果,因为无论如何,属性只是存储在对象上的字典中

import numpy as np


class Data_Read:
    def __init__(self, monthly_shape=(200, 200, 40)): #3D data
        months = [
            "jan",
            "feb",
            "march",
            "april",
            "may",
            "june",
            "july",
            "august",
            "sept",
            "oct",
            "nov",
            "dec"
        ]
        for month in months:
            setattr(self, month, np.zeros(monthly_shape))

    def detrend(self, month):
        # this is a dummy function that just increments
        return getattr(self, month) + 1