Epligam
Epligam

Reputation: 783

Python - Additional backslash is added to file path

I have some text file with these lines:

Zip=false
Run=false
Copy=true
FileName=c:\test\test.doc

Now I need to load this text file, change some values and write back to same text file. So I load it to a dictionary, change values on the dictionary and write back.

The problem is that that backslashes in the FileName path are being duplicate and in the new file I get FileName=c:\test\test.doc.

Here is the dictionary creation:

def create_dictionary(filename):
    try:
        file = open(filename, 'r')
    except:
        print("Error " + filename + " not found or path is incorrect")
    else:
        contents = file.read().splitlines()
        properties_dict = {}
        for line in contents:
            if not line.startswith("#") and line.strip():
                # print (line)
                x, y = line.split("=")
                properties_dict[x] = [y]
        return properties_dict

Here is writing back to the file

# Update the properties file with updated dictionary
fo = open(properties_file, "w")
for k, v in dic.items():
    print(str(k), str(v))
    fo.write(str(k) + '=' + str(v).strip("[]'") + '\n')
fo.close()

Upvotes: 1

Views: 1944

Answers (1)

This seems to be working:

def create_dictionary(file_name):
    try:
        properties_dict = {}
        with open(file_name, "r") as file:
            contents = file.read().splitlines()

        for line in contents:
            if not line.startswith("#") and line.strip():
                property_name, property_value = line.split("=")
                properties_dict[property_name] = property_value
        return properties_dict

    except FileNotFoundError:
        print(f"Error {file_name} not found or path is incorrect")


def dict_to_file(properties_dict, file_name):
    try:
        file_dirname = os.path.dirname(file_name)
        if not os.path.exists(file_dirname):
            os.makedirs(file_dirname)
    except FileNotFoundError: # in case the file is in the same directory and "./" was not added to the path
        pass

    with open(file_name, "w") as file:
        for property_name, property_value in properties_dict.items():
            file.write(f"{property_name}={property_value}\n")

properties_dict = create_dictionary("./asd.txt")
dict_to_file(properties_dict, "./bsd.txt")

Since, there was a request for more explanations, I am editing this post. Actually the critical part is not file.write(f"...") as @pktl2k pointed out. The critical part is changing properties_dict[x] = [y] to properties_dict[x] = y.

In Python strings, when you want to escape special characters you use a backslash ( \ ). The FileName parameter in your file has one of those special characters which is also a backslash (FileName=c:\test\test.doc). Thus, when you read this file, Python stores it as string as:

"c:\\test\\test.doc"

Which is totally normal. And when you want to write this string back to a file, you will get your desired output ( no double backslashes ). However, in your code, you do not have this value as a string. You have it as a list that is holding this value as string. When you call str built-in function on a list (which by the way is a built-in class), list class' __repr__ function is called (actually __str__ is called but in list __str__ calls __repr__ as far as I know, but let's not go so much into details of these functions. See this link if you want to learn more about it) to get a string representation of your list. In this process, all your list is converted to a string with all of its elements as it is. Then you get rid of some characters in this string representation using strip("[]'"), this is the actual cause of your problem.


Now, why did I write everything from the beginning and not only the part that is important as @pktl2k kindly asked. The reason is because if you noticed in create_dictionary function the author forgot to close the file using file.close(). This is a common problem and that's why there is a syntax like with open(....). I wanted to emphasis that: it is better to use with open(...) syntax whenever we would like to manipulate contents of a file. I could also write this as a small note as well, but I think it is better with this way (so it is a personal preference).

Upvotes: 2

Related Questions