1

I've got a Python program able to read files locally just fine:

In the directory where I have this program, there's a file called path_list (it's a list of file paths), and I can open and access it like so:

test_explicit = open('path_list').read()
print 'Reading local file gives: ' +  test_explicit

Then the program is going to loop through those paths and call the following function on each path, doing things based on what it finds in the version directory above. Unfortunately, here when I have absolute paths instead of relative, those same open/read operations are giving 'No such file or directory' errors. (But when I print out where it's trying to go and ls there, I see the contents I expect).

Here's the relevant part of my code:

    def getCommand(path):

      # Grab that trailing /version, strip the v, convert to int
      split_path = path.split("/")
      version = split_path.pop()
      version_num = int (version[1:] )

      # Increment that number, and remake path with a fresh /v(x+1) suffix
      version_num += 1
      new_suffix = '/v' + str(version_num)
      higher_file_path = '/'.join(split_path)
      higher_file_path += new_suffix

      finished_filename = 'finished.txt'
      finished_filepath = os.path.join(higher_file_path, finished_filename)

      result = open(finished_filepath).read()
      print 'Result is: ' + result
[more code]

When I run it I get a failure on the line with open and read():

IOError: [Errno 2] No such file or directory: '~/scripts/test/ABC/v4/finished.txt'

But when I ls or cd there I do see the file.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Diane Kaplan
  • 1,626
  • 3
  • 24
  • 34
  • '~' is expanded by the OS shell. Function `read()` does not use the shell for opening files and cannot do the expansion. You must convert a path that starts with a '~' to the absolute path first. – DYZ Feb 24 '17 at 19:33
  • I'm wrong- that WAS it- thank you! – Diane Kaplan Feb 24 '17 at 20:00

3 Answers3

4

You need to use following function to expand '~'

os.path.expanduser(path)

Update: In your case it may go as follows:

result = open(os.path.expanduser(finished_filepath)).read()
  • Thank you so much! I'd completely overlooked the ~. I've replaced it now and sadly I'm still getting the same issue. I'll update the description above to get rid of that bump in the road. – Diane Kaplan Feb 24 '17 at 19:54
1

~ is not a valid shortcut to /home/username/ or /Users/username/ in Python. You will need to use the full, expanded path.

os.path.expanduser() might be useful to you here.

  • If you attempt to answer, please be constructive. "You will need" is not constructive. – DYZ Feb 24 '17 at 19:36
  • I don't understand the reasoning for this criticism. Can you give me a constructive example of how to phrase my answers better in the future? For example, how is this markedly different than your comment made at approximately the same time that says: "You must convert a path that starts with a '~' to the absolute path first." is it the usage of the word "must" vs. "need"? I appreciate your guidance. – Scott Blevins Feb 24 '17 at 19:40
  • You just changed your answer to make it constructive. – DYZ Feb 24 '17 at 19:41
  • I changed my answer before I saw your comment because I wanted to add additional information. I don't believe that my answer was not constructive before. I was explaining that ~ isn't expanded automatically in Python and that they would need to use an expanded path instead. – Scott Blevins Feb 24 '17 at 19:45
  • Thank you so much! I'd completely overlooked the ~. I've replaced it now and sadly I'm still getting the same issue. I'll update the description above to get rid of that bump in the road. – Diane Kaplan Feb 24 '17 at 19:54
  • I'm wrong- that WAS it- thank you! – Diane Kaplan Feb 24 '17 at 20:00
1

As mentioned, you are using a shell special character ~ in your file path and that needs to be converted to a real path before opening. You can also allow environment variables in the path by doing this:

path = os.path.expanduser(os.path.expandvars(path))
tdelaney
  • 73,364
  • 6
  • 83
  • 116