首页 > 解决方案 > 是否可以控制如何在 python 中执行函数?

问题描述

我知道 python 非常灵活,几乎可以满足用户的任何需求。但是我从来没有见过也没有听说过这样的功能,并且在网上找不到任何相关的东西:是否可以逐步执行作为函数的变量?

def example_function():
  print("line 1")
  # stuff
  print("line 2")
  # stuff
  return(3)

def step_by_step_executor(fn):
  while fn.has_next_step():
    print(fn.current_step)
    fn.execute_step()
  return fn.return

step_by_step_executor(example_function) 
# print("line 1")
# line 1
# stuff
# print("line 2")
# line 2
# stuff
# return(3)
# returns 3

我想我可以使用inspect,exec和也许的组合来实现这样的东西__call__,但我很想看看是否有一个已经存在的名称和实现。

示例用例:

@do_y_instead_of_x
def some_function():
  do stuff
  do x
  do more
some_function()
# does stuff
# does y
# does more

@update_progress_bar_on_loops
def some_other_function():
  do stuff
  for x in range...:
     ...
  do more
some_other_function()
# does stuff
# initializes a progress bar, reports whats going on, does the loop
# does more

标签: pythonpython-3.xfunction

解决方案


您可以创建一个 Python 调试器pdb.Pdb实例并向其传递一个自定义的类文件对象,该对象实现了write选择性地输出调试器输出的代码部分的readline方法,以及始终向调试器发送n(简称next)命令的方法。由于调试器总是输出从函数返回的行两次,第二次前面有--Return--一行,你可以使用一个标志来避免输出多余的返回行:

import pdb

class PdbHandler:
    def __init__(self):
        self.returning = False

    def write(self, buffer):
        if buffer == '--Return--':
            self.returning = True

        # each line of code is prefixed with a '-> '
        _, *code = buffer.split('\n-> ', 1)
        if code:
            if self.returning:
                self.returning = False
            else:
                print(code[0])

    def readline(self):
        return 'n\n'

    def flush(self):
        pass

def example_function():
    print("line 1")
    print("line 2")
    return (3)

handler = PdbHandler()
print('returns', pdb.Pdb(stdin=handler, stdout=handler).runcall(example_function))

这输出:

print("line 1")
line 1
print("line 2")
line 2
return (3)
returns 3

推荐阅读