My Python app contains a subfolder called Tests which I use to run unit tests. All of my files are in the parent folder, which I will call App. The Tests folder contains, say, a test.py file. The App folder contains an app.py file and a file.txt text file.
In my test.py file, I can make my imports like this:
import sys
sys.path.append("PATH_TO_PARENT_DIR")
Say my app.py file contains the following:
class Stuff():
def do_stuff():
with open("file.txt") as f:
pass
Now if I run test.py, I get the following error:
FileNotFoundError: [Errno 2] No such file or directory: 'file.txt'
How can I fix this? Many thanks!
Assuming the file is located in the same folder as your script:
import os
parent_dir = os.path.abspath(os.path.dirname(__file__))
class Stuff():
def do_stuff():
with open(os.path.join(parent_dir, "file.txt")) as f:
pass
Explanation:
__file__ is the path to your script
os.path.dirname get's the directory in which your script sits
os.path.abspath makes that path absolute instead of relative (just in case relative paths mess your script up, it's good practice)
Then all we need to do is combine your parent_dir with the file, we do that using os.path.join.
Read the docs on os.path methods here: https://docs.python.org/3/library/os.path.html
A more explicit version of this code can be written like this, if that helps:
import os
script_path = __file__
parent_dir = os.path.dirname(script_path)
parent_dir_absolute = os.path.abspath(parent_dir)
path_to_txt = os.path.join(parent_dir_absolute, 'file.txt')
The open function looks for the file in the same folder as the script that calls the open function. So, your test.py looks in the tests folder, not the app folder. You need to add the full path to the file.
open('app_folder' + 'text.txt')
or move the test.py file in the same folder as text.txt
Related
Please note - this is NOT a duplicate of "how to open a file in the same folder as running script". I'm trying to do the opposite of it - I want to open the file in the root folder of the imported .py file, rather than the root of main.py which is the running script.
My file structure is as follows:
/email_sender/sender.py
/email_sender/template.html
main.py
Inside the main.py file I am importing the sender.py
My question is how to refer correctly to template.html from inside of the sender.py file?
The following doesn't work because it expectes the template.html to be in the root folder (where main.py is).
I know I can hardcode the path, but is it possible to refer to it in relation to sender.py?
with open('template.html', 'r') as f:
html = f.read()
import os
from sys import argv
try:
path = os.path.dirname(argv[0])
os.chdir(path)
except:
pass
You can do this in the main.py file and then to open the template will always be:
./email_sender/template.html
The directory structure:
├--- mod
| ├--- __init__.py
| └--- abc.data
└--- test.py
__init__.py:
with open("abc.data", 'r') as f:
pass # read and process the data
test.py:
import mod
The program above is expected to read the data in the file abc.data, but it gives an error instead:
FileNotFoundError: [Errno 2] No such file or directory: 'abc.data'
And this is because the current directory of Python interpreter is the parent directory of test.py.
So how to read abc.data in the module mod regardless of the location of test.py?
Actually the following code works:
__init__.py:
import os
filepath = os.path.join(os.path.dirname(os.path.realpath(__file__)), "abc.data")
with open(filepath, 'r') as f:
pass # read and process the data
But this solution is a bit dirty especially when there are many files to be read in __init__.py. Is there a more elegant solution?
I believe that's as good as it gets. Even larger libraries use the same method:
# Extracted From selenium/webdriver/firefox/firefox_profile.py
# ...
if not FirefoxProfile.DEFAULT_PREFERENCES:
with open(os.path.join(os.path.dirname(__file__),
WEBDRIVER_PREFERENCES)) as default_prefs:
FirefoxProfile.DEFAULT_PREFERENCES = json.load(default_prefs)
# ...
Another example:
# Extracted from pipenv/vendor/yaspin/spinners.py
# ...
THIS_DIR = os.path.dirname(os.path.realpath(__file__))
SPINNERS_PATH = os.path.join(THIS_DIR, "data/spinners.json")
# ...
If it was an importable object (e.g. .py files) then you can use . conventions to indicate the relative path.
Example:
I have my main file, main.py with this code:
import os
os.popen("start folder/subfile.py")
Then i have my other file, subfile.py with this code:
file = open("test.txt", "w")
file.close()
I want my subfile.py to create the test.txt file in its own folder, but it creates it in the main.py's folder.
So my question is, how do i make the subfile.py run from it own folder even though it's started from main.py
main.py folder : C:/users/user/Desktop
subfile.py folder: C:/users/user/Desktop/folder
In subfile.py, change the working directory (os.chdir) to the directory that contains the subfile.py file:
import os
os.chdir(os.path.dirname(__file__))
You can use subprocess instead which has that built in:
subprocess.Popen(sys.executable + ' subfile.py', cwd=os.path.dirname(__file__) + '/folder')
Try This :
import os
import inspect
your_current_folder_path = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
your_current_file_path = os.path.join(your_current_folder_path, "test.txt")
print(your_current_folder_path)
print(your_current_file_path)
with open(your_current_file_path, "w") as make_file:
make_file.write("")
print("Done.")
Another way: you can change your working directory by os.chdir("your_folder_directory") function.
os.chdir(r"C:/users/user/Desktop/folder")
I've something like this in my program:
A main script main.py inside a folder named 'OpenFileinaModule'. There's a folder called 'sub' inside it with a script called subScript.py and a file xlFile.xlsx, which is opened by subScript.py.
OpenFileinaModule/
main.py
sub/
__init__.py (empty)
subScript.py
xlFile.xlsx
Here is the code:
sub.Script.py:
import os, openpyxl
class Oop:
def __init__(self):
__file__='xlFile.xlsx'
__location__ = os.path.realpath(
os.path.join(os.getcwd(), os.path.dirname(__file__)))
print os.path.join(__location__, __file__)
self.wrkb = openpyxl.load_workbook(os.path.join(__location__,
__file__),read_only=True)
main.py:
import sub.subScript
objt=sub.subScript.Oop()
When I execute main.py, I get the error:
IOError: [Errno 2] No such file or directory: 'C:\\Users\\...\\OpenFileInaModule\\xlFile.xlsx'
It jumps the sub folder...
I've tried
__file__='sub/xlFile.xlsx'
But then the "sub" folder is duplicated:
IOError: [Errno 2] No such file or directory: 'C:\\Users\\...\\OpenFileInaModule\\sub\\sub/xlFile.xlsx'
How to open xlFile.xlsx with subScript.py from main.py?
you're overriding __file__ with __file='xlFile.xlsx', do you mean to do this?
I think you want something like
import os
fname = 'xlFile.xlsx'
this_file = os.path.abspath(__file__)
this_dir = os.path.dirname(this_file)
wanted_file = os.path.join(this_dir, fname)
I'd suggest always using the absolute path for a file, especially if you're on windows when a relative path might not make sense if the file is on a different drive (I actually have no idea what it would do if you asked it for a relative path between devices).
Please avoid using __file__ and __location__ to name your variables, these are more like builtin variables which might cause a confusion.
Note something here:
__location__ = os.path.realpath(
os.path.join(os.getcwd(), os.path.dirname(__file__)))
You have not included sub directory and the above joins only the CWD + os.path.dirname(__file__). This doesn't get you to the file. Please read the documentation of os.path.dirname: os.path.dirname(__file__) returns an empty string here.
def __init__(self):
file = 'xlFile.xlsx'
location = os.path.join('sub', file)
location = os.path.abspath(location) # absolute path to file
location = os.path.realpath(location) # rm symbolic links in path
self.wrkb = openpyxl.load_workbook(location)
using python code how can i get the files outside the current working directory
am working with e:\names\test.py directory
dirpath = os.path.dirname(os.path.realpath(__file__))
dirpath prints e:\names
in e:\images
how can i get the path e:\images\imh.png from the file test.py
Am hardcode the above path in test.py,how can i set the relative path inside test.py file
You can use:
os.path.split(os.getcwd())[0] to get the parent directory.
Then, you can use:
a=os.path.split(os.getcwd())[0]
os.listdir(a)
for listing the contents of the parent directory
Also, this works too:-
os.listdir(os.pardir)
import sys
import os
sys.path.insert(1, os.path.split(os.getcwd())[0] + '/directory_name')