Как (ленивые) данные загружать один и тот же большой набор данных из нескольких модулей Python - PullRequest
2 голосов
/ 29 октября 2019

У меня есть несколько модулей (python), в которых я использую одни и те же входные данные, а также переменные имеют одинаковые имена.

Я создал модуль data_loading.py, в котором создаются переменные. Затем я импортирую нужные мне переменные в модули data_analysis_xx.

Например,

" Module data_analysis_1 "
from data_loading import var_1, var_2,…, var_k 

" Module data_analysis_2 "
from data_loading import var_1, var_3

Таким образом, я избегаю копировать и вставлять те же 200 строк кода вкаждый модуль для загрузки одного и того же или частично одного и того же набора данных

Первый вопрос:

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

Проблема:

Однако, когда я импортирую data_loading, все переменные в нем загружаются / обрабатываются, даже еслиЯ на самом деле импортирую только одну или несколько переменных. Это может занять много времени, особенно потому, что в data_loading я также делаю некоторые базовые манипуляции с данными (проверка, разбиение, вырезание, сортировка и т. Д.)

Второй вопрос:

как сделать модуль data_loadingработать так, что только переменные, которые действительно должны быть загружены / обработаны, действительно обрабатываются?

Возможные решения

  1. разделение загрузки данных на несколько подмодулей -> немного уменьшаетпроблема, но увеличивает количество файлов для загрузки: сложность, caos, подвержены ошибкам. Не хорошо

  2. создать класс, который занимается загрузкой данных и загружает только переменную через класс? Как это сделать практически? Как мне тогда импортировать переменные? "из data_loading импортировать Loader.var_1 как var_1…, Loader.var_k как var_k"?

  3. реализовать отложенную загрузку -> Многие из моих переменных являются классами, которые имеют дело с фактической загрузкой данных (извлечение данных из файла). Следовательно, отложенная загрузка поможет сократить общую стоимость с точки зрения времени.

    Ссылки:

Ответы [ 2 ]

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

Один из способов решить все ваши проблемы - создать фабрику, которая будет создавать востребованные синглтоны.

С помощью этих двух шаблонов проектирования вы можете создавать экземпляры класса и создавать переменные только при необходимости (фабрика), и вы можете повторно использовать их, не вычисляя их снова в нескольких модулях (singleton)

Edit 1

Вот практическое приложение с примером псевдокода.

В моем скрипте мне нужна переменная для того, чтобы что-то накапливать. Эти переменные: число с определенным числом с плавающей запятой, число Фибоначчи с несколькими числами и простое число.

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

#compute_variables.py

def pi(n):
    pass

def fibonaci(n):
    pass

def prime_number(n):
    pass

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

Теперь мне нужен класс, который будет возвращать нужные вычисления vaibales, уже вычисленные в синглтоне (каждый раз возвращается только один объект)

#variables.py

class Calculus1:

    def __new__(cls):
        #singleton logic

    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def var1(self):
        return pi(self.a)

    def var2(self):
        return fibonaci(self.b)

    def var3(self):
        return prime_number(self.c)   

class Calculus2:

    def __new__(cls):
        #singleton logic

    def __init__(self, a, b, e):
        self.a = a
        self.b = b
        self.e = e

    def var1(self):
         return pi(self.a)

    def var2(self):
        return fibonaci(self.b)

    def var3(self):
        return prime_number(self.e)

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

# factory_meth.py

def  factory(var_class_name):
    # Factory logic here 
    myVars = CalculusX(x, y, z)
    return myVars

И наконец, я использовал всю эту реализациюв моем приложении.

from  factory_meth import factory

def fancy_something_1(f, g):
    vars = factory("Calculus2")
    return      (f * vars.vars1 / (vars.vars2 + vars.vars3))**g

def fancy_something_2(z ,h):
    vars = factory("Calculus2")
    return  z + vars.vars1 vars.vars2 + vars.vars3 + h   

С этой логикой все переменные будут вызываться и вычисляться только тогда, когда это необходимо (фабрика), где, даже если переменная вызывается, не будет вычислений, поскольку ее тот же объект возвращает(Singleton).

Примечание

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

1 голос
/ 31 октября 2019

Вы можете просто переместить действия, связанные с каждым набором данных, внутри функции, а затем импортировать эту функцию. Это может быть одна функция, которая принимает параметр для выбора набора данных, или несколько функций, возможно, одна функция на набор данных.

Одна функция на случай набора данных может выглядеть следующим образом:

def load_val_1():
    val_1 = ...  # Create and preprocess val_1 here
    ...
    return val_1

Затем вы from data_loading import load_val_1 создадите val_1, вызвав импортированную вами функцию. Функции могут быть даже статическими методами или методами класса, в этом случае вам нужно будет только импортировать этот класс.

...