How to read a file in Python function and call that function from some other python file? - python

Folder structure:
MainFolder
__init__.py
FolderA
Config.json
ConfigHelper.py
testA.py
FolderB
Test.py
ConfigHelper.py file:
import json
class ConfigHelper:
def read_config(self):
fileName = "Config.json"
with open(fileName, "r") as jsonfile:
return json.load(jsonfile)
When calling ConfigHelper.read_config() function from FolderB-->Test.py file , then
Getting Error: No such file or directory: 'config.json'
But if calling it from TestA.py file, No error is coming.
Look like it is taking path relative from the calling place.
Please tell me , How I can fix it?

When you are in FolderB there is no config.json file there.
Solutions
Run your script from MainFolder and pass correct path (FolderA/config.json).
Add folders to path, see.
Change working directory to FolderB before trying to read config.json, see.

You need to provide the full path to the file. You are right that it is looking for the relative path. When you are just passing the Config.json path it is looking in your current working directory for this.

path = os.getcwd()
print("Current Directory", path)
filepath = path + "/MainFolder/FolderA/Config.json"
Gave Full Path as above to fix the problem.

Related

How to open a file relative to imported .py file

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

Parent folder script FileNotFoundError

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

Python - How to open a file inside a module?

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)

Python open() requires full path

I am writing a script to read a csv file. The csv file and script lies in the same directory. But when I tried to open the file it gives me FileNotFoundError: [Errno 2] No such file or directory: 'zipcodes.csv'. The code I used to read the file is
with open('zipcodes.csv', 'r') as zipcode_file:
reader = csv.DictReader(zipcode_file)
If I give the full path to the file, it will work. Why open() requires full path of the file ?
From the documentation:
open(file, mode='r', buffering=-1, encoding=None, errors=None,
newline=None, closefd=True, opener=None)
file is a path-like object giving the pathname (absolute or relative
to the current working directory) of the file to be opened or an
integer file descriptor of the file to be wrapped.
So, if the file that you want open isn't in the current folder of the running script, you can use an absolute path, or getting the working directory or/and absolute path by using:
import os
# Look to the path of your current working directory
working_directory = os.getcwd()
# Or: file_path = os.path.join(working_directory, 'my_file.py')
file_path = working_directory + 'my_file.py'
Or, you can retrieve your absolute path while running your script, using:
import os
# Look for your absolute directory path
absolute_path = os.path.dirname(os.path.abspath(__file__))
# Or: file_path = os.path.join(absolute_path, 'folder', 'my_file.py')
file_path = absolute_path + '/folder/my_file.py'
If you want to be operating system agnostic, then you can use:
file_path = os.path.join(absolute_path, folder, my_file.py)
I have identified the problem. I was running my code on Visual Studio Code debugger. The root directory I have opened was above the level of my file. When I opened the same directory, it worked.
I've had considerable problems opening up files through Python if I don't use the absolute path or build the path using os.path. Even if the file is in the same directory as the Python file the result is the same. I used Chiheb's solution and of course it worked again (Thanks Chiheb). I do wonder if it's something going on with Python. I am using VS Code but still that shouldn't matter in my opinion if an accurate path is given.
The code for my current situation that worked using the solution above:
Sitka_highs.py
import os
import csv
absolute_path = os.path.dirname(os.path.abspath(__file__))
filename = absolute_path + '/data/sitka_weather_07-2018_simple.csv'
with open(filename) as f:
reader = csv.reader(f)
header_row = next(reader)
print(header_row)
I used below method and it worked fine for me.
FILE_PATH = os.path.dirname(os.path.realpath(__file__))
config = ConfigParser.ConfigParser()
config.readfp(open(FILE_PATH+'/conf.properties'))
I don't think Python knows which dir to use... to start with the current path of the current python .py file, try:
mypath = os.path.dirname(os.path.abspath(__file__))
with open(mypath+'/zipcodes.csv', 'r') as zipcode_file:
reader = csv.DictReader(zipcode_file)
Say that you are on the main_folder and want to call the file first_file.py that then opens the file readme.txt:
main_folder
│
└───first_folder
│ │ first_file.py
│ │
| └───second_folder
│ │ readme.txt
│
└─── ...
Python provides us with an attribute called __file__ that returns the absolute path to the file. For example, say that the content of first_file.py is just one line that prints this path: print(__file__).
Now, if we call first_file.py from main_folder we get the same result that if we call it from first_folder (note that, in Windows, the result is going to be a little bit different):
"/Users/<username>/Documents/github/main_folder/first_folder/first_file.py"
And if we want to obtain the folder of first_file.py, we import the library os and we use the method os.path.dirname(__file__).
Finally, we just concatenate this folder with the one we want to access from it (second_folder) and the name of the file (readme.txt).
Simplifying, the result code is:
import os
DIR_ABS_PATH = os.path.dirname(__file__)
README_PATH = os.path.join(DIR_ABS_PATH, 'second_folder', 'readme.txt')
And the value of README_PATH:
"/Users/<username>/Documents/github/main_folder/first_folder/second_folder/readme.txt"
This way, you also won't get any problems related to the Visual Studio Code debugger with the path and you'll be able to call the first_file.py from wherever you want 🥳

Python - set path to the directory in project

I created a project where my main.py script is in root folder Project. I have a utils directory inside and I want to get the path to this directory. I made a function which saves a .pdf file in my utils directory:
with open(os.path.abspath('utils/' + self.object.object_name+ '.pdf'), 'wb') as f:
f.write(pdf)
but I get an error:
IOError: [Errno 2] No such file or directory: '/home/documents/office/projects/me/utils/d.pdf'
How can I change os.path.abspath to do it the right way?
I want to get into utils directory always.
What you need is defining the path. And you can keep it relative.
yourPath = './utils/'
yourFileName = self.object.object_name+ '.pdf'
yourFullFileName = yourPath+yourFileName
and finally
with open(yourFullFileName, 'wb') as f:
f.write(pdf)
UPDATE
Following the small course Scott Hunter gave me, (cf his comment) I make amends. It follows that the correct way to build your path is :
working_dir = os.path.dirname(__file__)# __file__ is the full name of your working script
yourFullFileName = os.path.join(working_dir, 'util', self.object.object_name + "." + 'pdf')
By doing so, there is no assumption about the (operating-system dependent) separator.

Categories