Запутался в этой вложенной функции
Я читаю 3-е издание Python Cookbook и наткнулся на тему, обсуждаемую в 2.6 "Поиск и замена нечувствительного к регистру текста", где авторы обсуждают вложенную функцию, как показано ниже:
def matchcase(word):
def replace(m):
text = m.group()
if text.isupper():
return word.upper()
elif text.islower():
return word.lower()
elif text[0].isupper():
return word.capitalize()
else:
return word
return replace
Если у меня есть текст, как показано ниже:
text = 'UPPER PYTHON, lower python, Mixed Python'
и я печатаю значение 'text' до и после, замена происходит правильно:
x = matchcase('snake')
print("Original Text:",text)
print("After regsub:", re.sub('python', matchcase('snake'), text, flags=re.IGNORECASE))
Последняя команда "print" показывает, что подстановка происходит правильно, но я не уверен, как эта вложенная функция "получает":
PYTHON, python, Python
как слово, которое нужно заменить на:
SNAKE, snake, Snake
Как внутренняя функция заменяет получить свое значение?m
"?
Когда совпадает ('snake
') называется, слово принимает значение'snake
".
Непонятно, в чем ценностьm
' является.
Может ли кто-нибудь помочь мне понять это ясно, в этом случае?
Благодарю.
1 ответ
Когда вы передаете функцию в качестве второго аргумента re.sub
согласно документации:
он вызывается для каждого неперекрывающегося вхождения шаблона. Функция принимает один аргумент объекта соответствия и возвращает строку замены.
matchcase()
сама функция возвращает replace()
функция, поэтому, когда вы делаете это:
re.sub('python', matchcase('snake'), text, flags=re.IGNORECASE)
что происходит, что matchcase('snake')
возвращается replace
и затем каждое неперекрывающееся вхождение шаблона 'python'
как объект сопоставления передается в replace
функционировать как m
аргумент. Если это вас смущает, не волнуйтесь; это просто вообще сбивает с толку.
Вот интерактивный сеанс с гораздо более простой вложенной функцией, которая должна прояснить ситуацию:
In [1]: def foo(outer_arg):
...: def bar(inner_arg):
...: print(outer_arg + inner_arg)
...: return bar
...:
In [2]: f = foo('hello')
In [3]: f('world')
helloworld
Так f = foo('hello')
назначает функцию, похожую на приведенную ниже, переменной f
:
def bar(inner_arg):
print('hello' + inner_arg)
f
тогда можно назвать так f('world')
это как звонить bar('world')
, Я надеюсь, что это проясняет ситуацию.