【问题标题】:Regex Pattern to find arguments passed into a function正则表达式模式查找传递给函数的参数
【发布时间】:2021-12-31 13:37:52
【问题描述】:

对于一个项目,我正在尝试通读 python 文件并保留某个函数中正在使用的所有变量的列表。我正在阅读字符串格式的python文件中的行,然后专注于以“def”开头的行。出于本示例的目的,假设我们已识别出以下行:

def func(int_var:int,float_var=12.1,string_var=foo()):

我想使用正则表达式或任何其他方法来获取此函数声明中的值。

我想抓取字符串"int_var:int,float_var=12.1,string_var=foo()",然后根据逗号拆分得到["int_var:int","float_var=12.1","string_var=foo()"]

我在分离与“func”对应的括号之间的项目时遇到了很多麻烦。

任何帮助创建正则表达式模式将不胜感激!

【问题讨论】:

  • 我还想把函数名('func')作为一个单独的变量来获取!

标签: python regex re


【解决方案1】:

使用ast 模块比使用正则表达式更简单、更健壮:

import ast
s = """
def func(int_var:int,float_var=12.1,string_var=foo()):
   pass
"""
def form_sig(sig):
   a = sig.args
   d = [f'{ast.unparse(a.pop())}={ast.unparse(j)}' for j in sig.defaults[::-1]][::-1]
   v_arg = [] if sig.vararg is None else [f'*{sig.vararg.arg}']
   kwarg = [] if sig.vararg is None else [f'*{sig.kwark.arg}']
   return [*map(ast.unparse, a), *d, *v_arg, *kwarg]

f = [{'name':i.name, 'sig':form_sig(i.args)} for i in ast.walk(ast.parse(s)) 
        if isinstance(i, ast.FunctionDef)] 

输出:

[{'name': 'func', 'sig': ['int_var: int', 'float_var=12.1', 'string_var=foo()']}]

【讨论】:

  • 感谢您抽出宝贵时间撰写本文!超级好用。
【解决方案2】:
func_pattern = re.compile(r'^\s*def\s(?P<name>[A-z_][A-z0-9_]+)\((?P<args>.*)\):$')

match = func_pattern.match('def my_func(arg1, arg2):')
func_name = match.group('name') # my_func
func_args = match.group('args').split(',') # ['arg1', 'arg2']

【讨论】:

  • 我很感激!
  • 我注意到当逗号前后有空格时,此解决方案会失败。例如: 这有效 --> def foo(x,y,z=foo1()) 这失败了 --> def foo( x ,y , z=foo1()) 我试图查看识别参数的模式但无法确定如何修改它以允许空格。
  • 我不确定我是否理解。模式中的“.*”应该匹配括号之间的任何类型的字符,包括空格。快速检查一下我的结果表明您给出的两个示例的模式都匹配(在末尾添加一个冒号后,不以冒号结尾的字符串将不会与我给出的模式匹配)。也许问题是我们不希望输出中有空格?如果您想在获得匹配项后删除出现在参数周围的空格,您可以这样做: func_args = [arg.strip() for arg in match.group('args'),split(',')]
猜你喜欢
  • 2014-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-16
  • 2020-04-12
  • 1970-01-01
  • 2014-07-17
  • 1970-01-01
相关资源
最近更新 更多