在 python 个源 (.py) 文件中搜索和编辑行

Search and edit line(s) in python source (.py) files

我想通过关键字匹配在 python 源代码文件 (.py) 中搜索特定行并编辑找到的行,而且还能够编辑前行和后行。一切都以编程方式进行,以便我可以将其自动化。

是否有框架、工具或其他任何东西可以做到这一点?

更具体地说:

我必须修饰方法。我有一个包含所有方法及其相关装饰器的列表(我已经将其转换为 XML 文件)。由于我有 500 种方法,手动执行这些操作会花费太多时间。这就是为什么我想找到一种自动化的方法。

示例:

XML-文件

<methods>
   <method>
      <name>method_1</name>
      <decorator>xyz</decorator>
   </method>
   <method>
   ...
</methods>

源代码

在自动搜索结束编辑算法之前:

def method_1():
  ...

算法成功后:

@mark.xyz
def method_1():
  ...

Is there a framework, tool or anything else to do that?

在其他解决方案中,您可以使用 Emacs

来自FAQ

5.37 How do I perform a replace operation across more than one file?
Dired mode (M-x dired , or C-x d) supports the command dired-do-find-regexp-and-replace (Q), which allows users to replace regular expressions in multiple files.

关于这方面的一些事情,我包括了一个 replaceinsert 函数,用于您需要为特定任务执行的任何操作。您也可以使用 with 来避免 close 并将其全部捆绑在那里,老实说,它可以使用更多的重构,但如果这不能满足您的需求,则不想走得太远。

*添加了 if 语句,如果您不匹配关键字并且 return 出错,这将阻止您的整个文件被 w 选项擦除。

def find_edit(content, keyword):
    for i in range(len(content)):
        if content[i] == keyword:
            previous_line = i -1
            main_line = i 
            post_line = i + 1 
            return previous_line, main_line, post_line

def replace(position, replacer):
    content[position] =  replacer

def insert(position, insertion):
    content.insert(position, insertion)

filename = open('something.py', 'r')
content = filename.read().split('\n')
prev, main, post = find_edit(content, 'line 3')
filename.close()

if prev and  main and post:
    name = open('something.py', 'w')

    something = '@mark.xyz'
    replace(main, something)

    prev, main, post = find_edit(content, 'another_line 2')
    insert(post, something)
    content = ('\n').join(content)

    name.write(content)
    name.close()

输出

之前:

(xenial)vash@localhost:~/python/LPTHW$ cat something.py
line 1
line 2
line 3
some_line 1
some_line 2
some_line 3
another_line 1
another_line 2
another_line 3

之后:

(xenial)vash@localhost:~/python/LPTHW$ cat something.py
line 1
line 2
@mark.xyz
some_line 1
some_line 2
some_line 3
another_line 1
another_line 2
@mark.xyz
another_line 3