Существует ли метод Python для загрузки переменных объекта по мере необходимости? - PullRequest
1 голос
/ 17 октября 2019

Предположим, у вас есть большой сохраненный набор данных, который занимает значительное время для загрузки и вычисления различных аспектов набора данных, и вы пишете класс python для загрузки и предоставления множества атрибутов ваших данных для остальной части вашего кода python. Есть ли питонный способ выставления этих атрибутов таким образом, что они загружаются / вычисляются только тогда, когда это необходимо, и чтобы множественные запросы данных не загружали / не вычисляли их снова?

В качестве альтернативы, существует ли парадигма Iпропускаю что бы убрать необходимость в этом? Например, использовать метод для расчета / загрузки больших данных и просто убедиться, что я повторно использую вычисленные данные, а не пересчитываю их?

Это то, о чем я думал до сих пор, но такое ощущение, что я скучаючто-то.

def Dataset(object):
    def __init__(self, dataset_path):
        self.dataset_path = dataset_path

    @property
    def foo(self):
        try:
            return self._foo
        except AttributeError:
            self._foo = self.load_foo(self.dataset_path)
            return self._foo

    @property
    def bar(self):
        try:
            return self._bar
        except AttributeError:
            self._bar= self.load_bar(self.dataset_path)
            return self._bar

    def load_foo(self, dataset_path)
        # do things that take a lot of time
        return foo

    def load_bar(self, dataset_path)
        # do things that take a lot of time
        return bar

if __name__ == '__main__':
    dataset = Dataset('path/to/dataset')

    # use dataset information
    x = dataset.foo * 5
    y = dataset.foo + 3

Преимущество этого класса в том, что мне не нужно отслеживать, обращался ли я ранее к dataset.foo, кроме того, если я не в конечном итоге использую dataset.bar для этогоДля конкретного объекта время загрузки не теряется, как если бы я загружал панель в функции init.

Поскольку я использую все больше и больше переменных, это выглядит очень уродливо. Есть ли более питонный способ сделать это? или я вообще должен этим заниматься?

1 Ответ

2 голосов
/ 17 октября 2019

Что вы могли бы сделать, если больше ничего не собираетесь использовать для этого класса, так это для вас.

class Dataset(object):
    def __init__(self, dataset_path):
        self.dataset_path = dataset_path

    def __getattr__(self, item):
        try:
            super().__getattribute__(item)
        except AttributeError:
            self.__setattr__(item, self.load_named_attribute(self.dataset_path, item))
            return super().__getattribute__(item)

    def load_named_attribute(self, item_name):
        # this function should load the data based on the input name for now just return 5
        itemdata = 5
        return itemdata

a = Dataset('dummystr')
print(a.dummyvar)

Изменяет стандартный метод getattr, чтобы найти его с помощью исходного метода getattribute или, если он не установлен, пытается найти его в вашем пути к файлу данных.

...