Phani
Phani

Reputation: 3315

Imported code cannot open files in its directory

I have the following file structure:

test/
    test1.py
test2.py
text.txt

Here are the contents of the files

test1.py:

import sys
sys.path.append('../')
import test2

test2.read()

test2.py:

def read():
    with open('text.txt', 'rb') as f:
        print f.read()

if __name__ == "__main__":
    read()

text.txt contains a line of text. When I run test1.py, I get a "File not found" error:

Traceback (most recent call last):
  File "test1.py", line 5, in <module>
    test2.read()
  File "../test2.py", line 2, in read
    with open('text.txt', 'rb') as f:
IOError: [Errno 2] No such file or directory: 'text.txt'

I kind of understand why this error is coming up. But how do I deal with these kind of errors. I would like the code in test2.py to be like library code which I can use anywhere.

Upvotes: 0

Views: 509

Answers (3)

aIKid
aIKid

Reputation: 28252

Don't use relative path, then. Use the full path:

with open(r'C:\Somewhere\someplace\test.txt') as f:

Upvotes: 0

Elisha
Elisha

Reputation: 4951

sys.path used for python path (PYTHONPATH eviroment variable). i.e. where to look for python libraries when you import some library. it dose not effect where open() is looking for files.

when you open(filename). the filename is relative to the procees working directory. (the path the code was run from)

so if you want to access a flie that its path is relative to the path of the code file, then you can use the builtin variable __file__ which hold the current file path.

so you can change test2.py to be:

import os

def read():
    with open(os.path.join(os.path.dirname(__file__),'text.txt'), 'rb') as f:
        print f.read()

Upvotes: 5

CrazyCasta
CrazyCasta

Reputation: 28302

The proper way of doing what you're asking for is to use pkg_resources as described here. Basically something like the following would be what you want in test2.py:

import pkg_resources

def read():
    with pkg_resources.resource_stream(__name__, 'text.txt') as f:
        print f.read()

if __name__ == "__main__":
    read()

Upvotes: 3

Related Questions