gpt4 book ai didi

python - 对 Python 闭包感到困惑

转载 作者:太空宇宙 更新时间:2023-11-03 14:39:27 26 4
gpt4 key购买 nike

在 Mark Lutz 的“Learning Python 5th Edition”中 -(ISBN:9781449355739,第 17 章:“Scopes”,第 518 页,边栏:“Why You Will Care:Customizing open”)- 有以下插图:

import builtins

def makeopen(id):
original = builtins.open
def custom(*kargs, **pargs):
print('Custom open call %r:' % id , kargs, pargs)
return original(*kargs, **pargs)
builtins.open = custom

makeopen('spam')
F = open('script2.py')

makeopen('eggs')
F = open('script2.py')

预期输出:

Custom open call 'spam': ('script2.py',) {}
Custom open call 'eggs': ('script2.py',) {}

实际输出:

Custom open call 'spam': ('script2.py',) {}
Custom open call 'eggs': ('script2.py',) {}
Custom open call 'spam': ('script2.py',) {}

我对闭包的理解是它们应该返回多个副本每次调用 可变数据(即像其他语言中的实例变量)。

那么为什么“垃圾邮件”会打印两次?

我已经使用 PyCharm 调试器单步调试了代​​码,但我仍然不明白。

是不是因为变量 original 指向内置作用域中的对象而不是封闭作用域?

更新:

我认为问题是在第二次调用 makeopen() 时,变量 original 递归地指向 custom()。也许它最初的目的是作为一个“功能”:/...但我倾向于认为这是一个糟糕的例子。

这是一个按预期工作的解决方案:

import builtins

def makeopen(id):
def custom(*kargs, **pargs):
print('Custom open call %r:' % id , kargs, pargs)
return builtins.open(*kargs, **pargs)
return custom

file = 'script2.py'

f = makeopen('spam')
f(file)

g = makeopen('eggs')
g(file)

注意:上述解决方案实际上并没有改变 builtins.open 而是作为一个包装器。

最佳答案

makeopen('spam') 之后, open是一个打印“垃圾邮件”然后打开文件的函数。在makeopen('eggs')之后, open现在是一个打印“eggs”的函数,然后调用一个打印“spam”的函数,然后打开一个文件。

您正在连续包装 open在越来越多的层中发挥作用,最终得到:

print("eggs")
↳ print("spam")
↳ open(...)

关于python - 对 Python 闭包感到困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54514117/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com