谁能给我解释一下?关闭
Can anyone explain this to me? closure
我在阅读 realpython 中的闭包时看到了这段代码。
我真的很困惑,我不知道这些功能是什么以及它们的作用。
- 谁能给我解释一下吗?
point.get_x
, point.set_y
... 它们是什么?它们是属性吗?
>>> def make_point(x, y):
... def point():
... print(f"Point({x}, {y})")
... def get_x():
... return x
... def get_y():
... return y
... def set_x(value):
... nonlocal x
... x = value
... def set_y(value):
... nonlocal y
... y = value
...
... point.get_x = get_x
... point.set_x = set_x
... point.get_y = get_y
... point.set_y = set_y
... return point
...
>>> point = make_point(1, 2)
>>> point.get_x()
1
>>> point.get_y()
2
>>> point()
Point(1, 2)
>>> point.set_x(42)
>>> point.set_y(7)
>>> point()
Point(42, 7)
尽力解释——
所以,python 中的一切都是对象,所以函数也是对象。像对象一样,您可以将属性定义为函数,例如
... def point():
... print(f"Point({x}, {y})")
... point.get_x = get_x # you are setting an attribute of a function
... point.set_x = set_x
... point.get_y = get_y
... point.set_y = set_y
查看属性
point = make_point(1,2)
print(point.__dict__)
{'get_x': <function make_point.<locals>.get_x at 0x000002803CA924C0>, 'set_x': <function make_point.<locals>.set_x at 0x000002803CA92040>, 'get_y': <function make_point.<locals>.get_y at 0x000002803CA92A60>, 'set_y': <function make_point.<locals>.set_y at 0x000002803CA920D0>}
您可以使用 dot
表示法访问属性。
现在要结束了,请看函数get_x
... def get_x():
... return x
如你所见,get_x() 不接受 x
,那么它是如何知道 x
的?
print(point.get_x.__code__.co_freevars) # variables from parent scope
print(point.get_x.__code__.co_varnames) # local variables
print(point.get_x.__code__.co_names) # global variables
基本上 get_x
不知道 x,所以它检查它的父级是否有它。现在检查这个函数
def i_will_be_gone_after_call():
name = 'fade away'
def foo():
print(name)
return foo
some_var = i_will_be_gone_after_call()
# by this time i_will_be_gone_after_call call completes and popped out of call stack
some_var() # still prints `fade away` ? how
# because when defining foo, it saw that it does not know `name` variable, so it borrowed it from the parent function
# long after its parent function gone, it still remembers it and that is closure
some_var.__code__.co_freevars # ('name',)
现在来nonlocal
python2个都没有。在python 3、来到这个函数的时候
def set_x(value):
#nonlocal x
x = value
当您调用此函数时 python 将创建一个局部变量 x
并为其赋值。但是你想要的是替换你提供的值 x,它在父范围内。告诉 python 使用的方法是使用 nonlocal
.
def outer():
fruit = 'apple'
def inner():
fruit = 'lemon'
inner()
print(fruit)
return inner
outer() # --> will print apple not lemon
outer().__code__.co_varnames # ('fruit',) --> local variable, does not update fruit of outer
outer().__code__.co_freevars # ()
def outer():
fruit = 'apple'
def inner():
nonlocal fruit
fruit = 'lemon'
inner()
print(fruit)
return inner
outer() # --> will print lemon
outer().__code__.co_varnames # ()
outer().__code__.co_freevars # ('fruit',) --> points to parent scope
我在阅读 realpython 中的闭包时看到了这段代码。 我真的很困惑,我不知道这些功能是什么以及它们的作用。
- 谁能给我解释一下吗?
point.get_x
,point.set_y
... 它们是什么?它们是属性吗?
>>> def make_point(x, y):
... def point():
... print(f"Point({x}, {y})")
... def get_x():
... return x
... def get_y():
... return y
... def set_x(value):
... nonlocal x
... x = value
... def set_y(value):
... nonlocal y
... y = value
...
... point.get_x = get_x
... point.set_x = set_x
... point.get_y = get_y
... point.set_y = set_y
... return point
...
>>> point = make_point(1, 2)
>>> point.get_x()
1
>>> point.get_y()
2
>>> point()
Point(1, 2)
>>> point.set_x(42)
>>> point.set_y(7)
>>> point()
Point(42, 7)
尽力解释—— 所以,python 中的一切都是对象,所以函数也是对象。像对象一样,您可以将属性定义为函数,例如
... def point():
... print(f"Point({x}, {y})")
... point.get_x = get_x # you are setting an attribute of a function
... point.set_x = set_x
... point.get_y = get_y
... point.set_y = set_y
查看属性
point = make_point(1,2)
print(point.__dict__)
{'get_x': <function make_point.<locals>.get_x at 0x000002803CA924C0>, 'set_x': <function make_point.<locals>.set_x at 0x000002803CA92040>, 'get_y': <function make_point.<locals>.get_y at 0x000002803CA92A60>, 'set_y': <function make_point.<locals>.set_y at 0x000002803CA920D0>}
您可以使用 dot
表示法访问属性。
现在要结束了,请看函数get_x
... def get_x():
... return x
如你所见,get_x() 不接受 x
,那么它是如何知道 x
的?
print(point.get_x.__code__.co_freevars) # variables from parent scope
print(point.get_x.__code__.co_varnames) # local variables
print(point.get_x.__code__.co_names) # global variables
基本上 get_x
不知道 x,所以它检查它的父级是否有它。现在检查这个函数
def i_will_be_gone_after_call():
name = 'fade away'
def foo():
print(name)
return foo
some_var = i_will_be_gone_after_call()
# by this time i_will_be_gone_after_call call completes and popped out of call stack
some_var() # still prints `fade away` ? how
# because when defining foo, it saw that it does not know `name` variable, so it borrowed it from the parent function
# long after its parent function gone, it still remembers it and that is closure
some_var.__code__.co_freevars # ('name',)
现在来nonlocal
python2个都没有。在python 3、来到这个函数的时候
def set_x(value):
#nonlocal x
x = value
当您调用此函数时 python 将创建一个局部变量 x
并为其赋值。但是你想要的是替换你提供的值 x,它在父范围内。告诉 python 使用的方法是使用 nonlocal
.
def outer():
fruit = 'apple'
def inner():
fruit = 'lemon'
inner()
print(fruit)
return inner
outer() # --> will print apple not lemon
outer().__code__.co_varnames # ('fruit',) --> local variable, does not update fruit of outer
outer().__code__.co_freevars # ()
def outer():
fruit = 'apple'
def inner():
nonlocal fruit
fruit = 'lemon'
inner()
print(fruit)
return inner
outer() # --> will print lemon
outer().__code__.co_varnames # ()
outer().__code__.co_freevars # ('fruit',) --> points to parent scope