I am unable to do what I believe should be a simple import of a python3 module from a file's parent directory. I can get the module import to work from a parent directory without issue until I introduce a file descriptor into the file that is to be imported.
Example # 1 below is a 'works fine' scenario and # 2 is the problematic scenario that I'm hoping for suggestions on.
├── app
│ └── app.py
├── config.py
# app.py
import sys
sys.path.insert(0, '../')
from config import Config as conf
foo = conf.foo
if __name__ == '__main__':
print('hello from app main')
print(f'foo is --> {foo}')
#config.py
class Config():
foo = 'bar'
$ pwd
app/
$ python app.py
hello from app main
foo is --> bar
├── app
│ └── app.py
├── config.py
└── foo.txt <-- **Introduced new file here**
# app.py
import sys
sys.path.insert(0, '../')
from config import Config as conf
foo = conf.foo
if __name__ == '__main__':
print('hello from app main')
print(f'foo is --> {foo}')
# config.py
class Config():
with open('foo.txt', 'rt') as f:
foo = f.readline().rstrip()
# foo.txt
bar
$ pwd
app/
$ python app.py
Traceback (most recent call last):
File "app.py", line 3, in <module>
from config import Config as conf
File "../config.py", line 1, in <module>
class Config():
File "../config.py", line 2, in Config
with open('foo.txt', 'rt') as f:
FileNotFoundError: [Errno 2] No such file or directory: 'foo.txt'
What am I doing wrong here? And please note that foo.txt does in fact exist in the parent directory despite the "FileNotFoundError" error message.
$ cat ../foo.txt
bar
Thanks.
What am I doing wrong here?
You are using a relative path. This:
open("foo.txt")
will lookup foo.txt in the current working directory , whatever it is at this exact moment (which means that it can be just anything and that you should NEVER assume anything about it).
And please note that foo.txt does in fact exist in the parent directory despite the "FileNotFoundError" error message.
Yes, it exists in the parent directory, but not in the current directory.
The canonical solution here is to rebuild the proper path using os.path
functions and the __file__
magic variable:
# config.py
import os
def read_foo():
# build the full path to the current file
here = os.path.abspath(__file__)
# extract the directory path
dirpath = os.path.dirname(here)
# foo.txt is supposed to be in the same directory:
foopath = os.path.join(dirpath, "foo.txt")
with open(foopath) as f:
return f.readline().rstrip()
Now you can safely call config.read_foo()
from any other module, whatever the current working directory is.
As a side note: reading a file in a class
statement block is possibly not a great idea - not that it's illegal in Python but it's really a design smell...
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.