Python 如何修改 py 文件内函数的 docstring

2021-02-18 19:17:58 +08:00
 css3

有这么个需求,需要用 py 脚本修改一些 py 文件内的函数 docstring, 并保存覆盖

├── test.py
├── modify.py
# test.py 待修改 docstring 的函数文件

def hello_world():
    """
    this function is a demo, 需要修改这里,并保存到文件
    """
    return 'hello world'

    """
    # 这是一个干扰注释,不能修改这里
    """
# modify.py 修改 test.py 的 docstring 函数

from test import hello_world

def modify_docstring():

    print(hello_world.__doc__) # this function is a demo, 需要修改这里,并保存到文件

    hello_world.__doc__ = 'I\' am new docstring' 

    print(hello_world.__doc__) # I' am new docstring  # 这样可以赋值,但只是在内存中,怎么修改写入 test.py 文件呢?

1580 次点击
所在节点    Python
12 条回复
guyeu
2021-02-18 19:25:30 +08:00
难点在语法分析里。。不过只是识别 docstring 的话,感觉正则就行了。。
nthhdy
2021-02-18 19:52:17 +08:00
楼主 import 之后直接赋值 docstring 的方法,据我所知做不到改源文件的。
可以考虑用 ast module,parse 出来之后改,然后再生成代码。
xchaoinfo
2021-02-18 20:16:05 +08:00
ast
codists
2021-02-19 06:29:48 +08:00
个人认为这涉及到了文件读写。

```python
# modify.py 修改 test.py 的 docstring 函数

import re

input_f = open('test.py', 'r')
txt = re.sub(r'"""[\d\D]*?"""', r'""I\' am new docstring"""', input_f.read(), 1)

# 写入内容
output_f = open('test.py', 'w')
output_f.write(txt)

# 关闭文件
input_f.close()
output_f.close()

```
julyclyde
2021-02-19 15:47:14 +08:00
嘿,这是打算盗版谁家的软件产品啊
css3
2021-02-19 16:13:20 +08:00
@guyeu 正则怕误伤"友军"😂
css3
2021-02-19 16:16:39 +08:00
@nthhdy
@xchaoinfo 感谢老哥们,尝试了一下 ast,貌似把原来的多行 doc 给用'\n'合并成了一行去了,还没找到解决办法
@julyclyde 没有啊,老哥
@codists 多谢老哥,不优先考虑用正则,因为大量文件里边除了 docstring 用了三引号,还有大量注释,怕误伤友军😂
nthhdy
2021-02-19 17:44:21 +08:00
> 貌似把原来的多行 doc 给用'\n'合并成了一行去了,还没找到解决办法

感觉这个想办法解决一下就行了,就当是 IDE 的一个小功能呗,挺常见的,应不难搞。
css3
2021-02-19 18:19:57 +08:00
@nthhdy 最新发现解析后生成的 docstring 的三个引号也变成单引号了😂,感觉要处理起来也挺麻烦的
https://stackoverflow.com/questions/53564301/insert-docstring-attributes-in-a-python-file
css3
2021-02-19 20:18:06 +08:00
@nthhdy
@xchaoinfo
老哥们,我通过 ast 模块读取 python 文件函数的 docstring,然后通过 unpack 解析出来,发现原来 docstring 的三引号多行内容变成了单引号单行,是通过"\n"连接成单行的,这跟我想要的还是有点差距,我只是想在原有的 docstring 中增减一些描述,不需要也不能改变其结构,使用的代码完全复制的我楼上中链接中 stackoverflow 的
nthhdy
2021-02-19 20:55:23 +08:00
我看了一下 ast 的文档,int float string 这些 literal 在解析树上都表示为 Constant 对象,也就是说,string 是单引号、双引号还是三个引号,这个信息在解析树上已经丢失了。所以你想做这件事,ast 的确做不到。不知道是否有边角的配置或者 hack 的办法可以。

但这个思路是正解,先 parse 出来,做改动,再 dump 成代码。我没注意到 ast 的这个细节,所以只是工具不适合,可以再搜索一下同类型的工具。这么多做 code format 的工具呢,它们应该实现过类似的机制才对。

这个思路是个比较通用的解法,再复杂一些的需求也可以用这个路子。如果要解决的问题是一次性的,变体又有限,可以尝试用 adhoc 的办法。比如用正则,甚至写一个自己代码都适用的规则。看问题的规模和复杂度而定吧。
css3
2021-02-20 23:24:21 +08:00
@nthhdy 好的,多谢老哥指点了,还是采用了正则表达式

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/754013

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX