Да, я верю, что для регулярного выражения было бы невозможно сопоставить случаи, указанные в wim, когда вызов self скрыт.Тем не менее, здесь есть регулярное выражение, которое будет выполнять приличную работу для прямых вызовов по собственной личности (в форме funcname(...)
).Это регулярное выражение правильно сопоставляет все контрольные примеры, изложенные в исходном вопросе:
reobj = re.compile(r"""
# Match (unreliably) Python function with self reference.
^ # Anchor to start of line.
([ \t]*) # $1: Indentation of DEF statement.
def[ \t]+ # Function definition.
([^\s(]+) # $2: Name of function to find.
.*\r?\n # Remainder of function def line.
(?: # Zero or more lines w/o funcname.
(?: # Function block lines alternatives.
\1[ \t]+ # Func block lines have extra indentation.
(?:(?!\b\2\s*\().)* # Optional non-funcname stuff on line
| [ \t]*\#.* # Allow comment lines to defy indent rules.
)? # Allow blank lines in function block.
\r?\n # End of line not containing funcname.
)* # Zero or more lines w/o funcname
\1[ \t]+ # Now match the line having funcname.
(?:(?!\b\2\s*\().)* # Optional non-funcname stuff on line
\b\2\s*\( # Match the function self reference.
""", re.MULTILINE | re.VERBOSE)
Соответствует начиная со строки определения функции и фиксирует отступы перед пробелом 'def'
в группе $1
и функцииимя в группе $2
.Затем он сопоставляет строки в функциональном блоке, которые не содержат имя функции, каждое из которых имеет больше начальных пробелов, чем определение функции.Он пропускает пустые строки и строки, содержащие только комментарии.Он объявляет совпадение, как только находит в функциональном блоке строку с именем функции, за которым следуют левые скобки, указывающие на вызов самого себя.В противном случае он объявляет несоответствие, а затем продолжает поиск следующего возможного соответствия.
Обратите внимание, что это решение ненадежно и приведет к ложным срабатываниям, если имя функции встречается внутри строки или внутри комментария, следующего задругой код в строке.Он также не обрабатывает функции с многострочными необработанными строками.Тем не менее, он правильно поймает немало!