0

Имеется файл file.py, его содержимое вы найдёте ниже:

def as():
    print("Hello")
def das():
    print("World!")
as()

Требуется заменить строку 'as()' на 'das()'.

Я пробовал осуществить данное действие следующим кодом, но ничего не вышло, file.py не изменился.

file = open('file.py', 'r+')
for i in range(1, 5):
    file.readline()
file.write('das()')
file.close()

Как я должен изменить код #2, чтобы file.py изменился нужным мне образом?

Kromster
  • 13,809

1 Answers1

4

Во-первых, as - ключевое слово, его нельзя использовать в качестве имени функции. Поэтому я поменяю названия функций на пайтонические spam и eggs.

def spam():
    print("Hello")


def eggs():
    print("World!")


spam()

Во-вторых, как я уже писал, изменять текст исходного файла - это костыльное решение задачи, но всё же возможное:

lines = None
with open('file.py') as fh:
    lines = fh.readlines()

lines[-1] = 'eggs()'

with open('file.py', 'w') as fh:
    fh.write(''.join(lines))

Разумнее модифицировать не текст, а абстрактное синтаксическое дерево:

import ast

class CallChanger(ast.NodeTransformer):
    def visit_Call(self, node):
        if node.func.id == 'spam':
            node.func.id = 'eggs'
        return node


with open('file.py') as fh:
    tree = ast.parse(fh.read())
    CallChanger().visit(tree)
    code = compile(tree, filename='file.py', mode='exec')
    exec(code)

Но и это оверкилл для такого динамического языка, как Python. Ведь можно просто импортировать и вызвать что угодно в рантайме:

module_name = 'file'
func_name = 'eggs'

m = __import__(module_name)
f = getattr(m, func_name)
f()