简体   繁体   English

如何使用 python 修改文件内容?

[英]How to modify file content using python?

The following code reads a file, uses syntax tree to append fullstop to docstrings of that file.以下代码读取文件,使用语法树到 append 句号到该文件的文档字符串。 How can I save changes made in called file?如何保存在调用文件中所做的更改? I understand present code doesn't change content in original file but the local variables accessing it.我了解当前代码不会更改原始文件中的内容,而是访问它的局部变量。 Can you suggest changes, if possible provide learning resource as well?您能否提出更改建议,如果可能的话也提供学习资源?

astcode.py astcode.py

import ast
import sys
import os

filename = sys.argv[1]


# """Getting all the functions"""
ast_filename = os.path.splitext(ast.__file__)[0] + '.py'

with open(filename) as fd:
    file_contents = fd.read()

module = ast.parse(file_contents)

# with open(filename, 'w') as file:
# module level
if(isinstance(module.body[0], ast.Expr)):
    docstr = module.body[0].value.s
    if(module.body[0].value.s not in '.'):
        docstr += '.'
        # ast.dump(module, include_attributes=True)
    print(docstr)


# function level
function_definitions = [node for node in module.body if isinstance(node, ast.FunctionDef)]

for function in function_definitions:
    # next_node = function_definitions[idx].body
    next_node = function.body
    for new_node in next_node:
        if(isinstance(new_node, ast.Expr)):
            if(isinstance(new_node.value, ast.Str)):
                # Docstring stored in docstr variable.
                docstr = new_node.value.s

                if(docstr[-1] not in '.'):
                    new_node.value.s += '.'
                
                # astString = ast.dump(new_node, annotate_fields=True, include_attributes=True)
                # print(astString)
                # compile(astString, filename, 'eval')
                # print(exec(astString))
                print(new_node.value.s)

    # for line in module:
        # file.write(line)

Example例子

testfile.py测试文件.py

def readDictionaryFile(dictionary_filename):
    """readDictionaryfile doc string"""
    return []

def readTextFile(text_filename):
    """readTextfile doc string"""
    return []

$ python3 astcode.py testfile.py $ python3 astcode.py testfile.py

Expected预期的

testfile.py测试文件.py

def readDictionaryFile(dictionary_filename):
    """readDictionaryfile doc string."""
    return []

def readTextFile(text_filename):
    """readTextfile doc string."""
    return []

Note: Fullstop(.) appended.注意:附加句号(。)。

Looking at the documentation link, I notice there's a NodeVisitor and NodeTransformer with a code example.查看文档链接,我注意到有一个带有代码示例的 NodeVisitor 和 NodeTransformer。 I looked at how they unparse a function def, and it's basically the same as you've done in your original question, so I used that.我查看了他们如何解析 function def,它与您在原始问题中所做的基本相同,所以我使用了它。

# https://docs.python.org/3/library/ast.html#ast.NodeTransformer
class MyDocstringTransformer(ast.NodeTransformer):
    def visit_FunctionDef(self, node):
        if len(node.body):
            if isinstance(node.body[0], ast.Expr):
                if isinstance(node.body[0].value, ast.Constant):
                    if isinstance(node.body[0].value.value, str):
                        docstring = node.body[0].value.value
                        node.body[0].value.value = docstring + '.'
        return node

Using python 3.9's ast module gets us https://docs.python.org/3/library/ast.html#ast.unparse which is about as close as we can get to changing the ast node and then rewriting the original file.使用 python 3.9 的 ast 模块让我们得到https://docs.python.org/3/library/ast.html#ast.unparse节点然后重写原始文件即可.

tree = ast.parse(file_contents)
new_tree = MyDocstringTransformer().visit(tree)
print(ast.unparse(new_tree))

Instead of just overwriting to the same filename, you may want to write to a temp file, then let the OS attempt to delete the old file and rename the temp file to the old name, thus performing the replace in the OS.您可能希望写入临时文件,而不是仅仅覆盖相同的文件名,然后让操作系统尝试删除旧文件并将临时文件重命名为旧名称,从而在操作系统中执行替换。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM