Вот пример из стандартной библиотеки Python inspect.py. В настоящее время он читает
def strseq(object, convert, join=joinseq):
"""Recursively walk a sequence, stringifying each element."""
if type(object) in (list, tuple):
return join(map(lambda o, c=convert, j=join: strseq(o, c, j), object))
else:
return convert(object)
Он имеет в качестве параметров функцию преобразования и функцию соединения и рекурсивно просматривает списки и кортежи. Рекурсия реализована с помощью map (), где первый параметр - это функция. Код появился раньше, чем поддержка замыканий в Python, поэтому необходимы два дополнительных аргумента по умолчанию, чтобы передать преобразование и присоединиться к рекурсивному вызову. С закрытием это читается как
def strseq(object, convert, join=joinseq):
"""Recursively walk a sequence, stringifying each element."""
if type(object) in (list, tuple):
return join(map(lambda o: strseq(o, convert, join), object))
else:
return convert(object)
В объектно-ориентированных языках вы обычно не слишком часто используете замыкания, так как вы можете использовать объекты для передачи состояний и связанных методов, если они есть в вашем языке. Когда в Python не было замыканий, люди говорили, что Python имитирует замыкания с помощью объектов, тогда как Lisp эмулирует объекты с помощью замыканий. В качестве примера из IDLE (ClassBrowser.py):
class ClassBrowser: # shortened
def close(self, event=None):
self.top.destroy()
self.node.destroy()
def init(self, flist):
top.bind("<Escape>", self.close)
Здесь self.close - это обратный вызов без параметров, вызываемый при нажатии Escape. Однако для близкой реализации требуются параметры, а именно self, а затем self.top, self.node. Если бы у Python не было связанных методов, вы могли бы написать
class ClassBrowser:
def close(self, event=None):
self.top.destroy()
self.node.destroy()
def init(self, flist):
top.bind("<Escape>", lambda:self.close())
Здесь лямбда будет получать "себя" не из параметра, а из контекста.
person
Martin v. Löwis
schedule
02.11.2008