Хорошо, я начинаю понимать эту проблему немного больше. Закрытие действительно позволяет скрывать личные вещи. Вот простой пример.
Без закрытия:
# module named "foo.py"
def _bar():
return 5
def foo():
return _bar() - 2
С закрытием:
# module named "fooclosure.py"
def _init_module():
global foo
def _bar():
return 5
def foo():
return _bar() - 2
_init_module(); del _init_module
Пример использования:
>>> import foo
>>> dir(foo)
['__builtins__', '__doc__', '__file__', '__name__', '__package__', '_bar', 'foo']
>>>
>>> import fooclosure
>>> dir(fooclosure)
['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'foo']
>>>
Это на самом деле тревожно тонко. В первом случае функция foo()
просто имеет ссылку на имя _bar()
, и если вы удалите _bar()
из пространства имен, foo()
перестанет работать. foo()
ищет _bar()
каждый раз, когда запускается.
Напротив, закрывающая версия foo()
работает без _bar()
, существующего в пространстве имен. Я даже не уверен как это работает ... содержит ли оно ссылку на объект функции, созданный для _bar()
, или содержит ссылку на пространство имен, которое все еще существует, так что можно найти имя _bar()
и найти его?