简体   繁体   中英

Define variables for a Python function that is implemented outside of the current scope

I was wondering why the following works:

def wrapper():
    def wrap(p=10):
        def f():
            print(p)
        f()
    return wrap

f2 = wrapper()
f2()

But this doesn't:

def f():
    print(p)

def enhance(f):
    def wrap(p=10):
        f()
    return wrap

f2 = enhance(f)
f2() # NameError: name 'p' is not defined

Is there a way I can modify the second scenario so that variable p is defined? I was playing around with function decorators but couldn't figure it out how to expose the variables to the function I'm passing into the decorators.

I think I understand what you are really asking. You're taking about decorators, not variable scope. You say you can't figure out how to "expose the variables to the function I'm passing to the decorators." In your case 2, the function you are passing to enhance doesn't have any variables (arguments). Suppose we give it an argument, like this:

def f(p):
    print(p)

def enhance(f):
    def wrap(p=10):
        f(p)   # pass the argument to f
    return wrap

f2 = enhance(f)
f2()

Now you have a function, named enhance , which can be used as a decorator. The function to be decorated takes one argument. The decorator will replace this function with a new function, which can be called with one or zero arguments. If called with no arguments it will get the value "10" as a default.

Decorators replace one function with another function. In general it isn't the decorator's job to supply the arguments, except in the case of default arguments as you are trying to do. The arguments come from the code that calls the function.

because in example 2 you're referencing p that is not defined in one function and used as a parameter in the other function each of which is defined in their own scope.

in example 1 a function defined within the scope of another ie a nested function, has access to the outer functions scope (and therefore its variables)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM