python-装饰器函数内部的变量如何访问其作用域之外的值?

这是一个示例装饰器:

def smart_divide(func):
   def inner(a,b):
      print("I am going to divide",a,"and",b)
      if b == 0:
         print("Whoops! cannot divide")
         return

      return func(a,b)
   return inner

@smart_divide
def divide(a,b):
    return a/b

如果func是对象,那么如何从中访问变量a和b?

难道不是想要这样做吗?

def func(potato):
      print(y, x)

我有一个基本概念吗?这是Python某些模式的一部分在发生什么情况吗,还是在特殊情况下a和b因为生成器而需要查找?

更新资料

来自another stack exchange answer的新示例

def my_shiny_new_decorator(a_function_to_decorate):

    def the_wrapper_around_the_original_function():

        print("Before the function runs")

        a_function_to_decorate()

        print("After the function runs")

    return the_wrapper_around_the_original_function

def a_stand_alone_function():
    print("I am a stand alone function, don't you dare modify me")

发电机手动方式

a_stand_alone_function = my_shiny_new_decorator(a_stand_alone_function)
a_stand_alone_function()

发电机正确的方法

@my_shiny_new_decorator
def another_stand_alone_function():
    print("Leave me alone")

根据我从“手动”方式和“正确方式”获得新答案的地方,它们是相同的.

我认为这个示例可能导致我陷入困境,因为我试图将其扩展到涉及参数时.

我现在意识到我的想象没有任何意义

我以为我发布的原始代码与此等效

divide = smart_divide(divide(a,b))

如果执行,它将看起来像这样

def smart_divide(divide(a,b)):
   def inner(a,b):
      print("I am going to divide",a,"and",b)
      if b == 0:
         print("Whoops! cannot divide")
         return

      return func(a,b)
   return inner

但这将导致除法(a,b)在最上面一行执行

在新示例中,“ a_stand_alone_function”末尾没有().这意味着它被视为对象.

所以我的想法看起来像这样def smart_divide(divide(a,b)):没有意义,因为该函数将不再被视为对象

这使我对smart_devide如何获取作为参数传递的信息感到困惑.

最佳答案

smart_divide不会将a和b传递给它.它返回一个函数对象(内部函数),该函数将a和b传递给它.

您可以尝试以下操作,查看实际发生的情况:

def smart_divide(func):
   print("I am running in smart_divide; func=", func)
   def inner(a,b):
      print("I am going to divide",a,"and",b)
      if b == 0:
         print("Whoops! cannot divide")
         return

      return func(a,b)
   print("I am returning from smart_divide")
   return inner

print("I am running at top level before declaring divide")

@smart_divide
def divide(a,b):
    return a/b

print("The name 'divide' now refers to", divide)

print("I am now going to call the divide function")
divide(1, 2)

输出:

06001