使用AST将功能名称从CamelCase更改为snake_case [英] Using AST to change function names from CamelCase to snake_case

查看:59
本文介绍了使用AST将功能名称从CamelCase更改为snake_case的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此处,我当时是寻求一种将函数名称从CamelCase转换为snake_case的方法,这是使用AST建议的注释之一.我找到了一个代码片段来查找脚本中的所有函数

Here in this question, I was asking for a way to convert function names from CamelCase to snake_case, one of the comments suggested using AST. I found a code snippet to find all function calls in a script

import ast
from collections import deque


class FuncCallVisitor(ast.NodeVisitor):
    def __init__(self):
        self._name = deque()

    @property
    def name(self):
        return '.'.join(self._name)

    @name.deleter
    def name(self):
        self._name.clear()

    def visit_Name(self, node):
        self._name.appendleft(node.id)

    def visit_Attribute(self, node):
        try:
            self._name.appendleft(node.attr)
            self._name.appendleft(node.value.id)
        except AttributeError:
            self.generic_visit(node)


def get_func_calls(tree):
    func_calls = []
    for node in ast.walk(tree):
         if isinstance(node, ast.Call):
            callvisitor = FuncCallVisitor()
            callvisitor.visit(node.func)
            func_calls.append(callvisitor.name)

    return func_calls

if __name__ == '__main__':

    tree = ast.parse(open("some_dir").read())
    print(get_func_calls(tree))

使用此代码,我在脚本中拥有所有函数调用,现在我想编写一个将此名称转换为snake_case的代码.我找到了此代码段来修改AST树中的节点

using this code I have all function calls in my script, now I want to write a code that converts this name to snake_case. I found this code snippet to modify a node in AST tree

class RewriteName(ast.NodeTransformer):

    def visit_Name(self, node):
        return ast.copy_location(ast.Subscript(
            value=ast.Name(id='data', ctx=ast.Load()),
            slice=ast.Index(value=ast.Str(s=node.id)),
            ctx=node.ctx
        ), node)

tree = RewriteName().visit(tree)

我不知道如何使用它来实现我的目的.有任何解释或其他建议吗?

I didn't understand how to use it to serve my purpose. Any explanation or other pieces of advice?

推荐答案

我有点迟了,但也许将来会发现它.

I am kind of late to this, but maybe it will be found in the future.

无论如何,这是一个快速的技巧.实际上,您的解决方案就在那儿. name 方法返回您的名称,然后您可以随意更改它.因此,在您的 def get_func_calls(tree)调用中,您可以操纵字符串并将新名称重新分配给 Call 对象.

Anyway, here is a quick hack at it. Actually, you were almost there with your solution. The name method returns your name, then you can arbitrarily change that. So in your def get_func_calls(tree) call you can manipulate the string and re-assign the new name to the Call object.

ccName = callvisitor.name # work with some local var
new_name = ''             # the new func name
for char_i in range(len(ccName)): # go over the name
    if ccName[char_i].isupper():  # check if the current char is with uppercase
        if ccName[char_i - 1] == '.': # check if the previous character is a dot
            new_name += ccName[char_i].lower() # if it is, make the char to lowercase
        else:
            new_name += '_' + ccName[char_i].lower() # otherwise add the snake_
    else:
        new_name += ccName[char_i] # just add the rest of the lower chars
callvisitor._name = new_name       # just re-asign the new name 
func_calls.append(callvisitor._name)

这绝对不是一个很好的解决方案,它还取决于您是仅更改函数定义还是更改文件中的每个单个函数调用,但这应该使您了解如何更改 ast .

This is definitely not a pretty solution and it also depends if you want to change only function definitions or every single function call in a file, but this should give you an idea on how to change the ast.

这篇关于使用AST将功能名称从CamelCase更改为snake_case的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆