Запутался в этой вложенной функции

Я читаю 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'), Я надеюсь, что это проясняет ситуацию.

Другие вопросы по тегам