admin管理员组

文章数量:1122832

Where do I put a resource file so that it can be accessed from both src and test in PyCharm?

I've got a PyCharm project structured like this:

src
  scrabble
    board.py
    words.txt
test
  scrabble
    test_board.py

board.py contains this line:

with open('words.txt') as file:
    DICTIONARY = set(word.strip() for word in file)

Within test_board.py, which is a pytest file, I have this:

from scrabble.board import *

This works fine if I run board.py, but if I run test_board.py I get:

FileNotFoundError: [Errno 2] No such file or directory: 'words.txt'

Where can I put words.txt so that it can be accessed from either place? What path should I use in board.txt?

Edit: Someone pointed to How do I get the path and name of the python file that is currently executing?, which answers a different but related question. Indeed, if I put

import os
path = os.path.realpath('words.txt')
print(path)

inside board.py, I see different results when I run board.py

/Users/drake/PycharmProjects/algo_f24_solutions/src/scrabble/words.txt

vs when I run the tests in test_board.py:

/Users/drake/PycharmProjects/algo_f24_solutions/test/words.txt

The same code is looking for the same file in different place depending on whence it is run. Yes, I could hard-code the full path, but that wouldn't work if someone cloned this repo on another machine.

My question, clarified: within PyCharm, where can I put the file so that the same code can access it no matter where the code is run?

This is an assignment I'm giving to students, so I'd rather not ask them to reconfigure path settings or anything like that. I want it to work "out of the box".

Where do I put a resource file so that it can be accessed from both src and test in PyCharm?

I've got a PyCharm project structured like this:

src
  scrabble
    board.py
    words.txt
test
  scrabble
    test_board.py

board.py contains this line:

with open('words.txt') as file:
    DICTIONARY = set(word.strip() for word in file)

Within test_board.py, which is a pytest file, I have this:

from scrabble.board import *

This works fine if I run board.py, but if I run test_board.py I get:

FileNotFoundError: [Errno 2] No such file or directory: 'words.txt'

Where can I put words.txt so that it can be accessed from either place? What path should I use in board.txt?

Edit: Someone pointed to How do I get the path and name of the python file that is currently executing?, which answers a different but related question. Indeed, if I put

import os
path = os.path.realpath('words.txt')
print(path)

inside board.py, I see different results when I run board.py

/Users/drake/PycharmProjects/algo_f24_solutions/src/scrabble/words.txt

vs when I run the tests in test_board.py:

/Users/drake/PycharmProjects/algo_f24_solutions/test/words.txt

The same code is looking for the same file in different place depending on whence it is run. Yes, I could hard-code the full path, but that wouldn't work if someone cloned this repo on another machine.

My question, clarified: within PyCharm, where can I put the file so that the same code can access it no matter where the code is run?

This is an assignment I'm giving to students, so I'd rather not ask them to reconfigure path settings or anything like that. I want it to work "out of the box".

Share Improve this question edited Nov 21, 2024 at 18:02 Peter Drake asked Nov 21, 2024 at 17:39 Peter DrakePeter Drake 4524 silver badges18 bronze badges 2
  • Note that open('words.txt') looks for words.txt in the current directory. It will only work if you run board.py from src/scrabble. It will fall if you run, for example, python src/scrabble/board.py from the project root. – Schwern Commented Nov 21, 2024 at 18:16
  • os.path.realpath('words.txt') is meant to be run inside board.py – Schwern Commented Nov 21, 2024 at 18:47
Add a comment  | 

2 Answers 2

Reset to default 1

Inside board.py, don't just open the bare filename "words.txt".

Instead, use the __file__ variable to get the full pathname of the current python file, and use that to construct the full path to the words.txt file.

this_directory = os.path.dirname(__file__)
words_file = os.path.join(this_directory, "words.txt")
with open(words_file) as file:
    ...

Was this approach not obvious from the duplicate answer?

open('words.txt') looks for words.txt in the current directory. It will only work if you run board.py from src/scrabble. If it works when you run board.py directly in Pycharm, Pycharm must be setting the current working directory to src/scrabble. It will fall if you run, for example, python src/scrabble/board.py from the project root or anywhere else such as your testing directory.


os.path.realpath('words.txt') will not work for what you want. os.path.realpath will use the current working directory to make an absolute path. It will change if you change the directory you run the code from. For example, let's say we have this little program.

import os

print(os.path.realpath('words.txt'))

What we get depends on what directory we run it from.

PS C:\Users\Schwern> python tmp/test.py
C:\Users\Schwern\words.txt

PS C:\Users\Schwern> cd .\tmp\

PS C:\Users\Schwern\tmp> python test.py    
C:\Users\Schwern\tmp\words.txt

Instead, make it into an absolute path using __file__. __file__ is the location of the file the code is in.

Use os.path.dirname to get the directory board.py is in from __file__. Then os.path.join that with words.txt to get an absolute path.

import os

dir = os.path.dirname(__file__)
words_file = os.path.join(dir, 'words.txt')
print(words_file)

Now you get the same result no matter where you run from.

PS C:\Users\Schwern> python tmp/test.py
C:\Users\Schwern\tmp\words.txt

PS C:\Users\Schwern> cd tmp

PS C:\Users\Schwern\tmp> python test.py    
C:\Users\Schwern\tmp\words.txt

本文标签: pythonRead same file from src and test in PyCharmStack Overflow