0

I am trying to read a file in another directory. My current script is in path/to/dir. However, I want to read a file in ~/. I'm not sure how to do this.

I tried f = open("~/.file") but I am getting an error

IOError: [Errno 2] No such file or directory: '~/.file'

Liondancer
  • 15,721
  • 51
  • 149
  • 255

4 Answers4

3

This should work

from os.path import expanduser
home = expanduser("~")
  • There's no reason to just expand `~` by itself. Then you'd have to `os.path.join` it into the rest of the path. Easier to just expand `~/.file` in the first place, as in m.wasowski's answer. – abarnert Nov 08 '14 at 00:39
3

use os.path.expanduser:

import os
with open(os.path.expanduser('~/.file')) as f:
    print f.read()
abarnert
  • 354,177
  • 51
  • 601
  • 671
m.wasowski
  • 6,329
  • 1
  • 23
  • 30
2

os.path.expanduser will help you

ISanych
  • 21,590
  • 4
  • 32
  • 52
1

The short answer is: use os.path.expanduser, as m.wasowski shows:

f = open(os.path.expanduser("~/.file"))

But why do you have to do this?

Well, ~/.file doesn't actually mean what you think it does. It's just asking for a file named .file in a subdirectory named ~ in the current working directory.

Why does this work on the command line? Bcause shells don't just pass your arguments along as typed, they do all kinds of complicated processing.

This is why ./myscript.py *txt gives you ['./myscript.py', 'a.txt', 'b.txt', 'c.txt', 'd e f.txt'] in your argv—because the shell does glob expansion on *.txt by looking in the directory for everything that matches that pattern and turns it into a.txt b.txt c.txt "d e f.txt".

In the same way, it expands ~/.file into /Users/me/.file by looking at the appropriate environment variables and platform-specific defaults and so on. You can read the gory details for bash; things are similar with dash, tcsh, and most other shells (except Windows cmd and PowerShell).

Python talks to the filesystem directly, it doesn't go through the shell to do it. So, if you want to do the same things shells do, you have to do them explicitly: glob.glob, os.path.expanduser, os.path.expandvars, subprocess.check_output, etc.

The cool thing about doing it all in Python is that it works the same way everywhere. Even on Windows, where the shell doesn't know what ~/.file means, and the right answer may be some hideous thing like 'C:\\Documents and Settings\\me\\Documents' or '\\\\FileServer\\RoamingProfiles\\me', os.path.expanduser will give you the right hideous thing.

Community
  • 1
  • 1
abarnert
  • 354,177
  • 51
  • 601
  • 671