[英]Confused about Python closures
在Mark Lutz的“學習Python第5版”中 - (ISBN:9781449355739,第17章:“范圍”,第518頁,側欄:“你為什么要關心:自定義開放”) - 如下圖所示:
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(...)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.