0

Consider the program below, which purpose is to open some files, referenced by sys.argv[1] + "string".

import sys

def searchAndReplacePath(path):

    filesToSearch = [path + "\main\file1.txt",
                     path + "\main\folder\file2.txt"]

    for files in filesToSearch:
        with open(files, 'r') as inFile:
            filedata = inFile.readlines()

if __name__ == "__main__":
    # sys.argv[1] -- Specify which path should be used
    searchAndReplacePath(sys.argv[1])

At execution (Python 3.6, Windows 7) I receive an error:

Traceback (most recent call last):
  File "searchAndReplacePath.py", line 35, in <module>
    searchAndReplacePath(sys.argv[1])
  File "searchAndReplacePath.py", line 19, in searchAndReplacePath
    with open(file, 'r') as inFile:
FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\user\\main\\file1.txt'

Python adds backslashes to my backslashes! If I iterate the list and print() each item in said list, I get "single backslashes", so I don't really know what to do. I have read a lot about raw strings and how to use: r"path\to\file", but since I take my input from sys.argv[] I don't really now how to achieve the same result.

How do I open files, specified by a path provided via sys.argv[] in Python on Windows?

GLaDER
  • 345
  • 2
  • 17
  • 2
    "\" is a special character in many programming languages. E.g. `\n` will produce a "new line", `\t` will produce a "TAB" and so on. therefore, a string containing "\\" will print "\". Are you sure the two files exist at the specified location? – Laur Ivan Jun 26 '17 at 13:24
  • Check this out, it can help you: https://learnpythonthehardway.org/book/ex10.html Double backslash is expected as it is a special char in Python and can't be simply put as string. – Artur Jun 26 '17 at 13:25
  • I am fully aware, thank you. The issue at hand is related to Python not handling `\` and sys.arg as I expect. – GLaDER Jun 26 '17 at 13:28
  • Might be useful: https://stackoverflow.com/questions/16333569/mixed-slashes-with-os-path-join-on-windows – Grimmy Jun 26 '17 at 13:31
  • 1
    Your example code is inconsistent with the error. The paths in `filesToSearch` have multiple `\f` form-feed characters, in which case the error would actually be an invalid argument since that's an invalid character in Windows filenames. Instead you show the error as a file not found for the path `'C:\\Users\\user\\main\\file1.txt'`, in which the form-feed character has miraculously transmuted to an "f". – Eryk Sun Jun 26 '17 at 14:32

2 Answers2

1

Try using python's os module: import os files_to_search = [os.path.join(path, 'main\file1.txt') ... ]

Jason Stein
  • 714
  • 3
  • 10
  • This does not work. Instead of the aforementioned error I get: `No such file or directory: 'C:\\main\\file1.txt'`. I.e., only `C: ` is preserved from the `path` variable. – GLaDER Jun 26 '17 at 13:31
  • for debugging, can you post what happens if you call `>>> print (os.getcwd())` while in the directory containing your files? – Jason Stein Jun 26 '17 at 13:36
  • I get the current directory, without double backslashes. – GLaDER Jun 26 '17 at 13:39
  • However, `>>> newPath = os.getcwd()` followed by `>>> newPath` shows the double backslash scenario again. As I stated in my original post `print()` seems to do some magic. – GLaDER Jun 26 '17 at 13:41
  • 2
    After some more debugging I found the error. It was (like you stated, sorry for my stubbornness) a path error (i.e. I looked in the wrong dir). – GLaDER Jun 26 '17 at 13:51
  • :-) Nice of you to report that – holdenweb Jun 26 '17 at 22:16
1

The issue here is seen in the following interactive session:

>>> "\f"
'\x0c'
>>> '\\f'
'\\f'
>>> r'\\f'
'\\\\f'
>>> '\f'
'\x0c'
>>> r'\f'
'\\f'
>>>

As you can see, when the interpreter prints the repr of a string, it quotes the backslashes to reflect the Python source. '\f' is a single character, not two. When printing the filename, the interpreter is using its repr().

Also, note this difference:

>>> print('\"')
"
>>> '\"'
'"'

You will see that the repr() adds quotes around the value, showing it as it would be represented in a Python program.

holdenweb
  • 33,305
  • 7
  • 57
  • 77