3

Скажем, у меня есть функция или метод, который делает что-то повторяющееся, как проверка значения, перед выполнением каждой операции он делает, например, так:Есть ли способ украсить/выполнить операции над каждой строкой функции в Python?

def myfunc(): 
    if mybool: 
     do_operation_1() 
    else: 
     return 

    if mybool: 
     do_operation_2() 
    else: 
     return 

    ... 

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

Если у вас есть контроль над функциями работы, например, do_operation_N, вы можете украсить функции чем-то, что проверяет логическое значение.

Но что, если у вас нет контроля над отдельными операциями do_operation_N? Если для каждой строки в функции или методе я хочу, чтобы выполнялась одна и та же проверка, есть ли способ «вставить» ее без явного написания ее в каждой строке операции? Например, есть ли какая-то волшебница декоратора, с помощью которой я мог бы сделать следующее?

def magic_decorator(to_decorate): 
    def check(*args, **kwargs): 
     for call in to_decorate: #magic 
      if mybool: 
       to_decorate.do_call(call) #magic 
      else: 
       return #or break, raise an exception, etc 
    return check 

@magic_decorator 
def myfunc(): 
    do_operation_1() 
    do_operation_2() 
    ... 

Если есть способ достичь этого, мне все равно, если он использует декораторы или нет; Я просто хочу сказать «для каждой строки в функции/методе X, сначала сделать Y».

Примером «магии» описанного выше метода do_call является сокращение от того, что мне нужно, но оно будет сталкиваться с серьезными проблемами с выполнением отдельных строк вне порядка (например, если первая строка функции была назначение переменной, а второе - использование этой переменной, выполнение которых не соответствует требованиям, вызовет проблемы).

Чтобы быть ясным: возможность внешнего управления поэтапным порядком выполнения функции не То, чего я пытаюсь достичь: в идеале я бы просто реализовал то, что в естественном исполнении порядок, будет выполнять операцию каждый раз, когда myfunc что-то делает. Если «что-то» заканчивается ограничением «вызывает функцию или метод» (исключая задания, if чеки и т. Д.), Это нормально.

+0

Если вы не упростили, а 'mybool' может меняться между ними (или даже зависит от линии), вы можете просто сделать вызов' myfunc' условным. Полагаю, это не так просто, так что вы могли бы прояснить? – delnan

+0

Моя цель - дать проверку (например, 'mybool') и произвольную, потенциально очень длинную функцию/метод, чтобы применить условный/контрольный * без * вручную, делая каждую операцию условной. Я не самый лучший из этих вещей, поэтому, пожалуйста, отредактируйте/предложите изменения, чтобы сделать мою цель более ясной. –

+0

Я не понимаю, является ли условие всегда одинаковым и относится ко всем строкам. Если это так, вы можете значительно упростить его, не сбрасывая отдельные строки (просто вызовите/не вызывайте целую функцию). – delnan

ответ

6

Храните операции в последовательности, а затем использовать цикл:

ops = (do_operation_1, do_operation_2, do_operation_3) 

for op in ops: 
    if mybool: 
     op() 
    else: 
     return 
+0

все ((my_bool и op() или my_bool для op в ops)) – Liso

+0

@Liso: почему вообще 'или my_bool'? –

+0

в случае, если op() возвращает 'None' (например, не имеет' return') или 'False' – Liso

0

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

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

 Смежные вопросы

  • Нет связанных вопросов^_^