这是一个带有本地函数的简单函数:
def raise_to(exp):
def raise_to_exp(x, exp):
return pow(x, exp)
return raise_to_exp
现在我希望本地函数能够闭合exp
,但不知何故它没有。当我运行以下代码时:
square = raise_to(2)
print(square.__closure__)
我收到了“None”。我错过了什么吗?
这是一个带有本地函数的简单函数:
def raise_to(exp):
def raise_to_exp(x, exp):
return pow(x, exp)
return raise_to_exp
现在我希望本地函数能够闭合exp
,但不知何故它没有。当我运行以下代码时:
square = raise_to(2)
print(square.__closure__)
没有闭包,因为内部函数有它自己的本地变量exp; 你通过那个名字给它一个参数。参数掩盖了外部作用域中的名称,因此不会为它创建闭包。返回的函数需要两个参数,而对raise_to()
的参数被简单地忽略:
>>> from inspect import signature
>>> def raise_to(exp):
... def raise_to_exp(x, exp):
... return pow(x, exp)
... return raise_to_exp
...
>>> signature(raise_to(2))
<Signature (x, exp)>
>>> square = raise_to(2)
>>> square(5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: raise_to_exp() missing 1 required positional argument: 'exp'
>>> square(5, 3)
125
>>> raise_to('This is ignored, really')(5, 3)
125
如果您希望从外部函数中获取exp
参数,则需要从内部函数中删除该参数:
def raise_to(exp):
def raise_to_exp(x):
return pow(x, exp)
return raise_to_exp
exp
是一个闭包:>>> def raise_to(exp):
... def raise_to_exp(x):
... return pow(x, exp)
... return raise_to_exp
...
>>> raise_to(2).__closure__
(<cell at 0x11041a978: int object at 0x10d908ae0>,)
>>> raise_to.__code__.co_cellvars
('exp',)
co_cellvars
属性可以提供外部作用域中任何闭合变量的名称。raise_to()
的参数现在实际上被使用了。>>> raise_to(2)(5)
25
>>> raise_to('Incorrect type for pow()')(5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in raise_to_exp
TypeError: unsupported operand type(s) for ** or pow(): 'int' and 'str'