Как обеспечить выполнение функций в определенном порядке?

Я предпочитаю использовать селектор, и я применяю его в документе.

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

Например:

$(document).on("click", $(selector), function() {
    // Your code here
});
0
задан martineau 28 March 2019 в 00:39
поделиться

1 ответ

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

token1 = func1(token0)
token2 = func2(token1)
token3 = func2(token2)
...

Обычно токены также являются полезными результатами. В вашем примере: вы не позвоните transform_data, если у вас нет data, чтобы дать ему: data - это token0. Таким образом, transform_data будет называться после query_data.

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

[ 1135] Я просто обеспокоен тем, что в запутанном процессе было бы трудно проследить, есть ли у вас действительный ввод ... Разреженная матрица является недопустимым вводом для одного типа модели, но действительна для другого (комментарии) [1122 ]

В статически типизированных языках этого не произойдет (как правило), потому что программа не будет компилироваться, если вы дадите кролика, когда ожидается кот. В python, с вводом утки, это не так просто. Давайте посмотрим, как можно применить это:

  • хорошая документация
  • проверить входные данные
  • сгруппировать функции
  • заблокировать некоторые параметры [1131 ]

Хорошая документация

Это, безусловно, лучшее решение. Каждый здесь взрослый. Не волнуйся слишком сильно.

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

Проверьте входные данные

Это вариант Защитного программирования . Если необходимо, оберните функции, которые вам не принадлежат:

def wrap_transform_data(data, arg1, arg2):
    if not valid(data): # find a way to check this
        raise Exception("data is not valid")
    return transform_data(data, arg1, arg2)

Используйте исключения и избегайте блока try... except, так как быстрый сбой здесь лучше.

1141 Этого иногда будет недостаточно. Представьте, что у вас квадратная матрица: как проверить, была ли она транспонирована перед следующим вызовом функции?

Сгруппировать функции

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

Вы получаете что-то вроде этого:

def full_process(sql, arg1, arg2, frac_test, frac_validate, loss, learning_rate):
    data=query_data(sql)
    transformed_data=transform_data(data, arg1, arg2)
    train, test, validate = train_test_validate(transformed_data, frac_test, frac_validate)
    model = fit_model(train,test, loss, learning_rate)
    predictions, f1 = model.predict(validate)
    return ...

Как вы сказали, метод full_process имеет много смешанных параметров. Обычный способ справиться с этим в Python - это использовать значения по умолчанию:

def full_process(sql, arg1=1, arg2=2, frac_test=0.7, frac_validate=0.5, loss=0.2, learning_rate=0.1):
    data=query_data(sql)
    transformed_data=transform_data(data, arg1, arg2)
    train, test, validate = train_test_validate(transformed_data, frac_test, frac_validate)
    model = fit_model(train,test, loss, learning_rate)
    predictions, f1 = model.predict(validate)
    return ...

Он становится читаемым, если у вас нет разных параметров каждый раз:

full_process(sql, frac_validate=0.9)

Это решит транспонированный приведенный выше пример матрицы, если функция transpose является одной из функций.

Остерегайтесь: просто сгруппируйте детали без ответвлений . Не пишите что-то вроде этого:

def full_process(sql, , case1, case2, case3, arg1=1, arg2=2, frac_test=0.7, frac_validate=0.5, loss=0.2, learning_rate=0.1):
    data=query_data(sql)
    if case1:
        transformed_data=transform_data(data, arg1, arg2)
        train, test, validate = train_test_validate(transformed_data, frac_test, frac_validate)
        if case2:
            ...
        else:
            ...
    else:
        transformed_data=transform_data2(data, arg1, arg2)
        train, test, validate = train_test_validate(transformed_data, frac_test, frac_validate)
        if case2:
            ...
        else:
            ...

    return ...

Очень трудно читать, поддерживать, и это может привести к комбинаторному взрыву!

Заблокировать некоторые параметры

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

Я сосредоточусь на двух строках:

data=get_matrix()
transformed_data=transform_data(data, arg1, arg2)

Если вы хотите, чтобы пользователь вызывал transform_data с возвращаемым значением query_data, вы можете вернуть функцию:

def wrapped_query_data(sql):
    def ret(arg1, arg2) # you might use functools.partial 
        transform_data(data, arg1, arg2)
    return ret

Код теперь:

data_transformer = wrapped_query_data(sql)
train_test_validate = data_transformer(arg1, arg2) # no way the user can twist data here

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

Заключение

Есть ли лучший способ убедиться, что код выполняется в определенном порядке и что этот порядок очевиден из структуры кода?

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

0
ответ дан jferard 28 March 2019 в 00:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: