7
def main():
    fh = open('lines.txt')
    for line in fh.readlines():
        print(line)

if __name__ == "__main__": main()

Directory files

enter image description here

I am on for-working.py file, and am trying to access the lines.txt file within the same working directory. But I get error

No such file or directory: 'lines.txt'

Does python need to have an absolute path when opening files?

why doesn't this relative path work here?

Running python 3.6

EDIT ^1 I'm running visualstudio code with the python package extension by Don Jayamanne, and "Code Runner" package to compile/execute python code

EDIT ^2 Full error:

Traceback (most recent call last):
  File "c:\www\Ex_Files_Python_3_EssT(1)\Ex_Files_Python_3_EssT\Exercise Files\07 Loops\for-working.py", line 11, in <module>
    if __name__ == "__main__": main()
  File "c:\www\Ex_Files_Python_3_EssT(1)\Ex_Files_Python_3_EssT\Exercise Files\07 Loops\for-working.py", line 7, in main
    fh = open('lines.txt', 'r')
FileNotFoundError: [Errno 2] No such file or directory: 'lines.txt'

EDIT ^3 checking sys.path

import sys
print(sys.path)

produces this information:

['c:\\www\\Ex_Files_Python_3_EssT(1)\\Ex_Files_Python_3_EssT\\Exercise Files\\07 Loops', 
'C:\\Users\\Kagerjay\\AppData\\Local\\Programs\\Python\\Python36\\python36.zip', 'C:\\Users\\Kagerjay\\AppData\\Local\\Programs\\Python\\Python36\\DLLs', 'C:\\Users\\Kagerjay\\AppData\\Local\\Programs\\Python\\Python36\\lib', 'C:\\Users\\Kagerjay\\AppData\\Local\\Programs\\Python\\Python36', 'C:\\Users\\Kagerjay\\AppData\\Local\\Programs\\Python\\Python36\\lib\\site-packages']

EDIT ^4 checking os.getcwd()

Running

import os
print(os.getcwd())

Produces

c:\www\Ex_Files_Python_3_EssT(1)\Ex_Files_Python_3_EssT\Exercise Files

Well its definitely not in the right subdirectory (needs to cd 07 loops folder, that narrows the issue down

EDIT ^5 what is in lines.txt file

My lines.txt file i am opening looks like this. No extra whitespace or anything at start

01 This is a line of text
02 This is a line of text
03 This is a line of text
04 This is a line of text
05 This is a line of text

IN SUMMARY

Visual studio code's Code runner extension needs to be tweaked slightly to open files within a subdirectory so any of the below answers would provide a more robust solution to be independent of any extension / dependencies with the IDE

import os
print(os.getcwd())

Is most useful for diagnosing problem to the current directory python interpreter sees

Vincent Tang
  • 3,758
  • 6
  • 45
  • 63
  • 1
    Try to use `fh = open(os.path.join(os.getcwd(), 'lines.txt'))` – CLeo-Dev Aug 11 '17 at 13:29
  • What IDE are you using? – eyllanesc Aug 11 '17 at 13:29
  • Change `fh = open('lines.txt')` to `fh = open('lines.txt', 'r')` – GreenSaber Aug 11 '17 at 13:30
  • 2
    @GreenSaber `'r'` is the default argument and can be omitted. – Ma0 Aug 11 '17 at 13:30
  • none of these solutions work some reason – Vincent Tang Aug 11 '17 at 13:32
  • i dumped some more information on post hopefully this helps out? – Vincent Tang Aug 11 '17 at 13:33
  • 1
    What do you see when you `import sys; print (sys.path)` – Keatinge Aug 11 '17 at 13:33
  • @keatinge when running on cmd `sys.path` I get this error "The term 'sys.path' is not recognized as the name of cmdlet......" and then "object not found:(sys.path:string)[], commandnotfoundException" – Vincent Tang Aug 11 '17 at 13:34
  • @Kagerjay it's python code, put it in that same file – Keatinge Aug 11 '17 at 13:34
  • @Keatinge I added information when i ran a python program with only `import sys` and `sys.path` only in post – Vincent Tang Aug 11 '17 at 13:38
  • 1
    It's not `sys.path` what is relevant in this case, but `os.getcwd()`. Check the output of `import os; print(os.getcwd())`. If it is not the full path to the folder "07 Loops" then the Python interpreter is running from a different directory. Also, this is silly but sometimes happens, make sure the file "lines.txt" doesn't have any extra whitespace at the beginning or end of its name or something like that. – jdehesa Aug 11 '17 at 13:44
  • @jdhesa I edited my post, it definitely isn't in the right subdirectory, how would I fix this? Lines.txt doesn't have any whitespace in beginning – Vincent Tang Aug 11 '17 at 13:46

4 Answers4

8

Get the directory of the file, and join it with the file you want to open:

def main():
    dir_path = os.path.dirname(os.path.realpath(__file__))
    lines = os.path.join(dir_path, "lines.txt")
    fh = open(lines)
    for line in fh.readlines():
        print(line)

if __name__ == "__main__": main()
thaavik
  • 3,257
  • 2
  • 18
  • 25
2

This should do the trick.

def main():
    fh = open('lines.txt')
    for line in fh.readlines():
        print(line)

if __name__ == "__main__":
    import os

    curr_dir = os.path.dirname(os.path.realpath(__file__))  # get's the path of the script
    os.chdir(curr_dir)  # changes the current path to the path of the script
    main()
Ma0
  • 15,057
  • 4
  • 35
  • 65
  • this works but I feel like that's alot of excessive code though, its not really the pythonic way of doing things – Vincent Tang Aug 11 '17 at 13:51
  • I don't think this is a great solution. You shouldn't need to change the working directory of the process just to open a file. This may have unneeded side effects for other parts of the process. See my answer for a more robust solution, which is to determine the absolute path of the file. – thaavik Aug 11 '17 at 14:01
0

I faced the same trouble today. The solution was outside the code, in the environment.

Shows the picture of VSCode settings editor

Command prompt in VSCode opens with the directory where VSCode executable is placed. When you execute the code, Python is searching for the file in the location where the VSCode executable is located.

This setting can be changed to the directory that you are working in(shown in figure). So when you are running the code in yourprog.py file, the interpretor is started in your working directory.

Then the VScode runner will do the way you are thinking.

-1

okay summary of working solutions to my problem from others not mentioned in post

Direct absolute path manually

def main():
    fh = open('lines.txt')
    for line in fh.readlines():
        print(line)

if __name__ == "__main__":
    import os

    curr_dir = 'c:\\www\\Ex_Files_Python_3_EssT(1)\\Ex_Files_Python_3_EssT\\Exercise Files\\07 Loops'
    os.chdir(curr_dir)
    main()

I commented out unnecessary parts ... and open(lines at beginning

Below solution is very good for lazy implementation tests (e.g. copy-paste template), since all the absolute path correction code is up top seperated from everything else (my preferred solution)

import os
dir_path = os.path.dirname(os.path.realpath(__file__))
lines = os.path.join(dir_path, "lines.txt")
# open(lines)
# ...

def main():
    fh = open(lines)
    for line in fh.readlines():
        print(line)

if __name__ == "__main__": main()

Most robust solution would be this one below, since its self-contained only in the function definition when main() gets called. Original answer didn't include the import os so I included it here

def main():
    import os
    dir_path = os.path.dirname(os.path.realpath(__file__))
    lines = os.path.join(dir_path, "lines.txt")
    fh = open(lines)
    for line in fh.readlines():
        print(line)

if __name__ == "__main__": main()
Vincent Tang
  • 3,758
  • 6
  • 45
  • 63
  • See my edited answer. The ellipsis (...) was just meant to be a placeholder for your code, not actual code. – thaavik Aug 11 '17 at 14:00
  • that's strange it still runs though even with `...` does the python interpreter ignore it like comments? – Vincent Tang Aug 11 '17 at 14:01
  • it says the `...` is an eillpisis object / placeholder https://stackoverflow.com/questions/42190783/what-does-three-dots-in-python-mean-when-indexing-what-looks-like-a-number – Vincent Tang Aug 11 '17 at 14:07