【问题标题】:create DataManager class which only downloads/creates datasets once called and not yet created创建 DataManager 类,它只下载/创建数据集,一旦调用但尚未创建
【发布时间】:2020-12-18 11:32:57
【问题描述】:

因此,我正在努力提高我的 OO 技能,并且正在开展一个需要使用不同数据集的项目。我有三个数据集,我们称它们为first_datasecond_datathird_data。我从它们各自的来源下载这些并将它们保存到pandas.DataFrames 中,每个数据集的一个方法称为make_*_data()* 替换数据的名称。

我有一个名为 DataManager 的类构建,如下所示:

class DataManager:
    """ Manages the datasets for this project.

    TODO: add caching method to check for already downloaded files.
    TODO: apply Singleton pattern to this class
    """

    def __init__(self):
        self._first_data = None
        self._second_data = None
        self._third_data = None

    @property
    def first_data(self):
        if self._first_data is None:
            self._first_data = make_first_data()
        return self._first_data

    @property
    def second_data(self):
        if self._first_data is None:
            self._first_data = make_second_data()
        return self._first_data

    @property
    def third_data(self):
        if self._first_data is None:
            self._first_data = make_third_data()
        return self._first_data

现在,我不完全确定这是否是一个好方法,但这似乎可以解决问题。但是,我现在想对我拥有的每个数据集执行操作,例如训练 kNN 模型。我想要类似循环所有数据集的东西,并且已经研究过使用__getattr____getitem__,但是我在这里的森林里有点迷路,所以我正在寻找建议。

我的目标是在以下几行中发挥作用:

for dataset in DataManager.datasets:
    # perform action for dataset

我正在寻找一种很好、干净的方式来实现它。我试过定义

# the __init__
    self._datasets = {
        "first_data": self._first_data,
        "second_data": self._second_data,
        "third_data": self._third_data
    }

# the properties

def __getitem__(self, item):
    return self._datasets[item]

但这不起作用,因为它将返回None。我可以用属性而不是私有属性替换DataManager.datasets 中的所有项目,但这只会在我想避免的初始化时运行所有下载。有什么建议吗?

【问题讨论】:

    标签: python database oop iterator


    【解决方案1】:

    我建议通过子类化 dict 的替代方法 (注意:UserDict 包装了 dict)。

    您还可以对其进行调整以符合您所需的类接口(此处未完成):

    from collections import UserDict
    
    class Datasets(UserDict):
        def _load(self, key):
            # load data for this specific key
            print("Loading data...")
            return "loaded {} data from somewhere".format(key)
    
        def __missing__(self, key):
            self[key] = self._load(key)
            return self[key]
    
    datasets = Datasets()
    
    print(datasets["first"])
    print(datasets["second"])
    print()
    print(datasets["first"])
    print()
    print(datasets)
    print()
    for dataset in datasets.values():
        print(dataset) # process dataset
    

    输出:

    Loading data...
    loaded first data from somewhere
    Loading data...
    loaded second data from somewhere
    
    loaded first data from somewhere
    
    {'first': 'loaded first data from somewhere', 'second': 'loaded second data from somewhere'}
    
    loaded first data from somewhere
    loaded second data from somewhere
    

    当然,您必须处理无法加载数据集或指定了错误的数据集名称/键的情况。

    【讨论】:

    • 谢谢你,这看起来是实现它的好方法。我试试看!
    • @GroenteLepel,不客气,对我来说它看起来也更简单。
    猜你喜欢
    • 1970-01-01
    • 2012-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-31
    • 2018-05-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多