so my program import a utils that reads a file in the same directory as the utils. However, this utils function can be called from different files from different directory.
Project
|
|-module_1:
|__ init __.py
| file.py <--- calls util.load_file()
|module_2:
| __ init __.py
| utils.py <---- load_file() path used 'file.txt'
| file.txt
what is this thing called ? I couldn't even search for it. tried package managment, expanding path ...etc
__file__ contains the path to the current file. Check it with print(__file__).
pathlib from Pythons standard library can be used to construct an absolute path to the data file.
import pathlib
print(pathlib.Path(__file__))
print(pathlib.Path(__file__).parent)
print(pathlib.Path(__file__).parent / 'file.txt')
You can now open your file like this:
filepath = pathlib.Path(__file__).parent / 'file.txt'
with open(filepath) as f:
for line in f:
print(line)
Related
I am trying to read a file in a custom module I have created in Python. But it is showing error when I try to do so.
Directory structure
base/
|
|_ app.py
|_ cmod/
|
|_ __init__.py
|_ util.py
|_ db.csv
util.py snippet
from csvhandler import CSVFile
def get_db():
with open("db.csv", "r+") as db:
data = CSVFile(db)
return data
app.py snippet
from cmod import util
data = util.get_db()
It throws the following error
FileNotFoundError: [Errno 2] No such file or directory: 'db.csv'
Is there any issue with imports of placement?
Note: The db.csv has to be put there only.
The current working directory when you run this is likely the one app.py sits in. open() looks for files in the current working directory, not the directory of the currently executing file.
The most portable way to open a file stored relatively would be to get the full path to the python file, isolate the directory, and then join it.
util.py
import os
def get_db():
directory = os.path.dirname(__file__)
with open(os.path.join(directory, "db.csv"), "r+") as db:
data = CSVFile(db)
return data
Let's consider this directory structure:
package/
rooster.py
files/
rooster.txt
app/
main.py
and the content of the two Python files:
rooster.py:
def roost():
file = open('files/rooster.txt')
return file.read()
main.py:
from package.rooster import roost
print(roost())
Running main.py returns an error:
FileNotFoundError: [Errno 2] No such file or directory: 'files/rooster.txt'
That obviously happens because the working directory is app/ and there's no app/files/rooster.txt file. Thus the error. What solution does Python provide for such a scenario?
Maybe you can use the full path of the file, this should work, if it is always the same
Solution:
I am not sure if I understood the issue correctly, but this code might solve your issue.
rooster.py
def roost(path):
import os
file = open(os.path.join(path, 'files/rooster.txt'))
return file.read()
main.py
import os
from pathlib import Path
from rooster import roost
p = Path(__file__).parents[1]
package_dir = os.path.join(p, 'package')
print(roost(package_dir))
OUTPUT:
Hello World1
Hello World2
Hello World3
Directory Structure:
testCode/
package/
rooster.py
files/
rooster.txt
app/
main.py
Let me know in case there is any issue.
I have a folder structure like so:
main/
__init__.py
files/
__init__.py
a.csv
b.yml
subfolder/
__init__.py
code.py
In code.py, I want to use the files in the files folder as so:
# HOW DO I IMPORT a.csv and b.yml
# from main.files import a -- this doesn't work
class Code():
def func(file_a, file_b):
# do something
Is this something I can do? How do I do this?
If code.py is in the same folder as your files (.csv and .yml) you don't have to import them instead you can open them and read them within the function like so:
import csv
import yaml
file_a = 'a.csv'
file_b = 'b.yaml'
class Code():
def func(file_a, file_b):
with open(file_a) as f_obj:
read = csv.reader(f_object)
# do something with opened file
with open("example.yaml", 'r') as stream:
another_read = yaml.safe_load(stream))
# do something with opened file
I think your second file is supposed to be a .yaml file not a .yml file.
I have a python package with this file structure:
package
- bin
clean_spam_ratings.py
- spam_module
- data
spam_ratings.csv
__init__.py
spam_ratings_functions.py
Contents of clean_spam_ratings.py:
import spam_module
with open(path_to_spam_ratings_csv, 'r') as fin:
spam_module.spam_ratings_functions(fin)
What should I set path_to_spam_ratings_csv to?
If you are in a module, then you can get the absolute path for the directory that contains that module via:
os.path.dirname(__file__)
You can use then that to construct the path to your csv file. For example, if you are in spam_ratings_functions.py, use:
path_to_spam_ratings_csv = os.path.join(os.path.dirname(__file__), "..", "data", "spam_ratings.csv")
Is there any way to get the current archive name in Python?
Something like
EggArchive.egg
Lib
---SomePythonFile.py
From SomePython.py, is there anyway to fetch the .egg name?
The variable __file__ contains the path to the current python file. So If you have a structure:
.
`- your.egg
`-your_module.py
And in your_module.py you have a function:
def func():
print(__file__)
The the code:
import sys
sys.path.append('/path/to/your.egg')
from your_module import func
func()
Will print out:
/path/to/your.egg/your_module.py
So basically you can manipulate the __file__ variable if you know where relatively your module is inside the egg file and get the full path to the egg.
To get the relative path to the egg in the script that's in the egg file you'll have to do:
def rel_to_egg(f):
my_dir = os.path.dirname(os.path.abspath(f))
current = my_dir
while not current.endswith('.egg'):
current = os.path.dirname(current)
return os.path.relpath(current, my_dir)
Now let's say __file__ == '/test/my.egg/some/dir/my_script.py':
>>> print(rel_to_egg(__file__))
'../..'