Returning function from function in Python
Вопрос
I am a newbie to Python, i am having some doubts on working of below mentioned code snippet from shutil module.
def ignore_patterns(*patterns):
"""Function that can be used as copytree() ignore parameter.
Patterns is a sequence of glob-style patterns
that are used to exclude files"""
def _ignore_patterns(path, names):
ignored_names = []
for pattern in patterns:
ignored_names.extend(fnmatch.filter(names, pattern))
return set(ignored_names)
return _ignore_patterns
When a call to shutil.copytree
is made with ignore
option set to ignore_patterns
, then it calls ignore_patterns
function and returns a function. My doubts are:
1) ignore_patterns
when called will return the _ignore_pattern
function reference. Now when this function will be called, how is it still accessing the "patterns" list? Once called function "ignore_patterns" has returned, list patterns which was created at its call should be available for its called scope only.
2) What is the signicance of underscore in the returned function _ignore_patterns
function name?
Решение
This is called a closure, and it's a general feature of languages that allow nested functions. Inner functions can close over variables in an outer scope, and will retain a reference to that name when they are called from outside the outer function.
The underscore is just to signify that _ignore_patterns
is an inner function, while keeping the name of the returned function similar. It could be called anything you like.
Другие советы
ignore_patterns
when called will return_ignore_pattern
function reference. Now when this function will be called, how it is still accessing the "patterns" list.This is fine.
_ignore_pattern
is a closure. That means it keeps around all the local variables (including function parameters) that it needs to do its job. Eventually the garbage collector will get it, but not while it might still be needed.What is the signicance of underscore in returned function
_ignore_patterns
function name?The author just wanted to disambiguate the names. It beats calling the closure
f
. Which is what I would have done.