如何进行 python 元编程以传递代码块(如 ruby yield)

How to do python meta programming to pass code blocks around (like ruby yield)

与ruby一样,如何传递代码块并在传递的地方执行(yield)。我正在尝试在 python 3.5 中实现同样的目标 这就是我的伪代码的样子。如何实现我想要做的事情。我必须做出哪些改变?

# Calculate all
# I want this function should yield whatever method passed to it

# THIS MUST BE A CLASS
class Calculator:

  def __init__(self):
    self.prefix = "hello"

  def calculate(self, function_name)
    local_val = 10
    print("executing {} function with {}".format(function_name, self.prefix))
    result = function_name(local_val)
    print(result)
    return result



# I want to pass these functions to Calculator().calculate() method

def add_one(x):
  return x+1

def minus_one(x):
  return x-1

def divide_in_half(x):
  return x/2



Calculator().calculate(add_one(?))
# expect this to print:
# executing add_one function with hello
# 11


Calculator().calculate(minus_one(?))
# expect this to print:
# executing minus_one function with hello
# 9

Calculator().calculate(divide_in_half(?))
# expect this to print:
# executing divide_in_half function with hello
# 5

函数是 Python 中的对象,因此您可以这样做:

Calculator().calculate(add_one)
Calculator().calculate(minus_one)
Calculator().calculate(divide_in_half)

请注意,这会传递 函数本身 而不是函数名称。 (在您的代码中,您必须访问 function_name.func_name 才能获取函数名称,因此我建议将 function_name 重命名为 fn,这是 "function." 的缩写)

您甚至不需要声明预定义函数。您可以使用 lambda 语法即时传递匿名调用:

# Instead of add_one, for example:
Calculator().calculate(lambda x: x + 1)

首先,修复您的 __init__,使其在没有参数的情况下调用时不会抱怨:

def __init__(self, prefix="hello")

calculate 完成的对 format 的调用中使用函数 __name__:

msg = "executing {} function with {}"
print(msg.format(function_name.__name__, self.prefix))

然后传递函数对象:

Calculator().calculate(add_one)
# expect this to print:
# executing add_one function with hello
# 11


Calculator().calculate(minus_one)
# expect this to print:
# executing minus_one function with hello
# 9

Calculator().calculate(divide_in_half)
# expect this to print:
# executing divide_in_half function with hello
# 5