V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
css3
V2EX  ›  Python

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

  •  
  •   css3 · 2021-02-18 19:17:58 +08:00 · 1690 次点击
    这是一个创建于 1401 天前的主题,其中的信息可能已经有所发展或是发生改变。

    有这么个需求,需要用 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 文件呢?
    
    
    12 条回复    2021-02-20 23:24:21 +08:00
    guyeu
        1
    guyeu  
       2021-02-18 19:25:30 +08:00
    难点在语法分析里。。不过只是识别 docstring 的话,感觉正则就行了。。
    nthhdy
        2
    nthhdy  
       2021-02-18 19:52:17 +08:00
    楼主 import 之后直接赋值 docstring 的方法,据我所知做不到改源文件的。
    可以考虑用 ast module,parse 出来之后改,然后再生成代码。
    xchaoinfo
        3
    xchaoinfo  
       2021-02-18 20:16:05 +08:00 via Android
    ast
    codists
        4
    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
        5
    julyclyde  
       2021-02-19 15:47:14 +08:00
    嘿,这是打算盗版谁家的软件产品啊
    css3
        6
    css3  
    OP
       2021-02-19 16:13:20 +08:00
    @guyeu 正则怕误伤"友军"😂
    css3
        7
    css3  
    OP
       2021-02-19 16:16:39 +08:00
    @nthhdy
    @xchaoinfo 感谢老哥们,尝试了一下 ast,貌似把原来的多行 doc 给用'\n'合并成了一行去了,还没找到解决办法
    @julyclyde 没有啊,老哥
    @codists 多谢老哥,不优先考虑用正则,因为大量文件里边除了 docstring 用了三引号,还有大量注释,怕误伤友军😂
    nthhdy
        8
    nthhdy  
       2021-02-19 17:44:21 +08:00
    > 貌似把原来的多行 doc 给用'\n'合并成了一行去了,还没找到解决办法

    感觉这个想办法解决一下就行了,就当是 IDE 的一个小功能呗,挺常见的,应不难搞。
    css3
        9
    css3  
    OP
       2021-02-19 18:19:57 +08:00
    @nthhdy 最新发现解析后生成的 docstring 的三个引号也变成单引号了😂,感觉要处理起来也挺麻烦的
    https://stackoverflow.com/questions/53564301/insert-docstring-attributes-in-a-python-file
    css3
        10
    css3  
    OP
       2021-02-19 20:18:06 +08:00 via iPhone
    @nthhdy
    @xchaoinfo
    老哥们,我通过 ast 模块读取 python 文件函数的 docstring,然后通过 unpack 解析出来,发现原来 docstring 的三引号多行内容变成了单引号单行,是通过"\n"连接成单行的,这跟我想要的还是有点差距,我只是想在原有的 docstring 中增减一些描述,不需要也不能改变其结构,使用的代码完全复制的我楼上中链接中 stackoverflow 的
    nthhdy
        11
    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
        12
    css3  
    OP
       2021-02-20 23:24:21 +08:00 via iPhone
    @nthhdy 好的,多谢老哥指点了,还是采用了正则表达式
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1264 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 18:04 · PVG 02:04 · LAX 10:04 · JFK 13:04
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.