I have some test code:
def num(num):def deco(func):def wrap(*args, **kwargs):inputed_num = numreturn func(*args, **kwargs)return wrapreturn deco@num(5)
def test(a):return a + inputed_numprint test(1)
when run this code, I got an error shows that 'inputed_num' is not defined
My question is:
In wrap function, is there not a closure that func can got 'inputed_num' ?
Anyway, If not, how should I do to got my aim: Initialize some value, and use this value directly in the main function.
Thinks.
No, there isn't a closure like that. Functions can close over variables that are present in the surrounding lexical context, not in the calling context. In other words, if you actually write one function in another, then the inner one can have access to variables in the outer one:
def f():g = 2def f2():print gf2()
But functions never have access to variables inside the function that called them.
In general there isn't a way to do what you want, viz., set an arbitrary variable in a function from outside the function. The closest thing is you could use a global inputed_num
in your decorator to assign inputed_num
as a global variable. Then test
would access the global value.
def num(num):def deco(func):def wrap(*args, **kwargs):global outsideroutsider = numreturn func(*args, **kwargs)return wrapreturn deco
@num(5)
def test(a):print a+outsider>>> test(2)
7
But of course the variable setting is then global, so multiple concurrent uses (e.g., recursion) wouldn't work. (Just for fun, you can also see here for a very arcane way to do this, but it is way too crazy to be useful in a real-world context.)