Search code examples
pythonregexrefactoringstr-replaceautomated-refactoring

What is the best way to replace a function call in a script?


Consider this line of Python:

new_string = change_string(old_string)

If you want to replace or remove the function call and just have new_string = old_string, a simple text replacement will not suffice. (Replacing "function_changes_string(“ with the empty string will leave the closing parenthesis. What if you wanted to replace the function call 100 or more times. That’s a lot of wasted time.

As an alternative, I'm using a regex to replace the function call.

Here is a short python script that takes as input the name of function to remove.

import os
import re

# Define variables
current_directory = os.getcwd()
file_to_regex_replace = "path/to/script/script.py"
output_filepath = current_directory + "/regex_repace_output.py"
regex_to_replace = re.compile(r"function_changes_string\((.+?)\)")
fixed_data_array = []

#read file line by line to array
f = open(file_to_regex_replace, "r")
data = f.readlines()
f.close()

line_count = 0
found_count = 0
not_found_count = 0
for line in data:
    line_count += 1
    # repace the regex in each line
    try:
        found = re.search(regex_to_replace, line).group(1)
        found_count += 1
        print str(line_count) + " " + re.sub(regex_to_replace, found, line).replace("\n", "")
        fixed_data_array.append(re.sub(regex_to_replace, found, line))
    except AttributeError:
        fixed_data_array.append(line)
        not_found_count += 1

print "Found : " + str(found_count)
print "Total : " + str(not_found_count + found_count)

# Open file to write to
f = open(output_filepath, "w")

# loop through and write each line to file
for item in fixed_data_array:
    f.write(item) 
f.close()

This worked fine and did what I expected. However, is there another, more accepted way to do this?


Solution

  • Using a regex is probably the simplest way to handle your use case. But use the regex match and replace functionality likely built into your IDE instead of reinventing the wheel by writing your own script.

    Note that many IDEs have powerful automated refactoring capabilities built into the application. For example, PyCharm understands the notion of extracting method calls as well as renaming variables/methods, changing method signatures, and several others. However, PyCharm currently does not have a built-in refactoring operation for your use case, so regex is a good alternative.

    Here's an example regex that works in Atom:

    Find:      change_string\((.+)\)
    Replace:   $1
    

    Given the line new_string = change_string(old_string), the resulting line after replacement will be new_string = old_string.

    If you are writing software for a company that has a relatively large codebase, then large-scale refactoring operations might happen frequently enough that the company has developed their own solution to your use case. If this might be the case, consider asking your colleagues about it.