Importing from sub-folder hierarchy in python - python

i am trying to import specified modules from test_file hierarchy
something like :
test_case1.py
test_subsuite_2
test_sub_2.1.1.py
test_suite2
is it possible to do a run import on this hierarchy
/project/main.py
/project/test_files
test_files folder hierarchy is like this :
test_files
test_suite1
test_case1.py
test_subsuite_1
test_sub1_1.py
test_sub1_2.py
test_subsuite_2
test_subsuite_2_1
test_sub_2.1.1.py
test_sub2_1.py
test_sub3_2.py
test_suite2
test_case2.py
test_subsuite2_1
test_sub21_1.py
test_sub21_2.py
test_subsuite2_2
test_sub22_1.py
test_sub23_2.py

Create an empty file called __init__.py in all you folders. Then you can import using . as a folder separator. Documentation here.

The key is to create a blank file __init__.py on all subfolders containing the files you want to import.
In your case, you will have to create the __init__.py files on all of the following folders-
test_files
test_files\test_suite1
test_files\test_suite1\test_subsuite_2
test_files\test_suite1\test_subsuite_2\test_subsuite_2_1
Also, when you import files be careful about specifying the import path correctly, with the entire path from the topmost level specified, and with different folder levels separated by a .
For example, you must import test_case1 by specifying :
from test_files.test_suite1 import test_case1
Similarly, test_subsuite_2 can be imported by specifying :
from test_files.test_suite1 import test_subsuite_2

Related

Python: importing file from another subdirectory

I have a directory structure like:
mycode
|
└-----dirA
| └─---- fileA.py
└─----dirB
└─---- fileB.py
How do I import fileB.object from fileA.py? I have __init__.py's in all the folders, including "mycode", but I continually get errors that I can't find fileB.py from fileA.py, and relative imports don't work either.
In python, there's a unique way of traversing the tree backwards:
One period . for same directory
Two periods .. for parent directory
Three periods for grand-parent...
You get the point
Try using:
from ..dirB.fileB import <symbol>
if the python outputted the result that you can't find the folders, you must set the directory properly like
it should be C:\Users\Desktop\DirectoryName
instead of FolderDirectory:FolderName
i mean you should set the proper path of the directory, since a program is not really that smart that can locate it easily, but just a bunch of instructions that you wanted to do it properly
You may use sys.path.insert() method:
import sys
sys.path.insert(0, './subdirectory')
import myfile
and you can read more about it here

How to read files located in different directories inside a project?

I stetted up a Spyder project where I have codes located in a specific folder and different datas in different folders. Basically, I would like to read those files using the relative path or a simple approach. Let's take the project tree below as example:
Project Tree
I am trying to read "dummy_csv.csv" using "dummy_code.py".
What I am currently doing is this:
import pandas as pd
filepath= "../../../../../dummy_folder02/untitled folder/untitled folder/untitled
folder/dummy_data/dummy_csv.csv"
pd.read_csv(filepath)
I wonder if there is a more elegant/cleaner way of doing this...
You can include the root dir of your data in the system path variable, and then use just the relavtive path:
import sys
sys.path.append(<absolute path to root data dir>)
filepath = "<relative path to csv file, in relation to the absolute path added to sys.path>"
for example:
sys.path.append("C:/my_datasets/dummy_folder02")
filepath = "untitled folder/untitled folder/untitled folder/dummy_data/dummy_csv.csv"

How to normalize a relative path using pathlib

I'm trying to use relative paths in Python, and I want to put my csv files in a separate folder from my python code.
My python program is in the following folder:
G:\projects\code
I want to read this file which is one level up:
G:\projects\data\sales.csv
How do I specify a path using pathlib that is one level up from my current working folder? I don't want to change the current working folder.
I tried this:
from pathlib import Path
file = Path.cwd() /'..'/'data'/'sales.csv'
But now the 'file' variable equals this:
'G:/projects/code/../data/sales.csv'
I read through the docs and either it isn't explained there or I'm just missing it.
Although it's not a problem that your path includes '..' (you can still use this path to open files, etc. in Python), you can normalize the path using resolve():
from pathlib import Path
path = Path.cwd() / '..' / 'data' / 'sales.csv'
print(path) # WindowsPath('G:/projects/code/../data/sales.csv')
print(path.resolve()) # WindowsPath('G:/projects/data/sales.csv')
NB: I personally would name a variable that contains a path path, not file. So you could later on do file = open(path).
print(
Path(__file__).parent, # the folder
Path(__file__).parent.parent, # the folder's parent
sep='\n'
)
print(
Path(
Path(__file__).parent.parent, 'hello.py'
)
)
results in
C:\Users\isik\Desktop\Python\MessAround\project\module
C:\Users\isik\Desktop\Python\MessAround\project
C:\Users\isik\Desktop\Python\MessAround\project\hello.py
with this file structure
-project
-module
-__init__.py
-hello.py
-__init__.py
while the code is located inside project.module.__init__.py
Do you mean "read my csv files"?
The import keyword has a different meaning in Python (you import only other Python modules).
In any case, in order to read a file located one folder above your Python file, you can use this:
import os
filePath = os.path.dirname(__file__)+'/../'+fileName
fileDesc = open(filePath)
fileData = fileDesc.read()
fileDesc.close()
...
here is an example I used:
import json
from pathlib import Path
def read_files(folder_name, file_name):
base_path = Path.cwd().joinpath('configs','resources')
path = base_path.joinpath(folder_name,file_name)
open_file = open(path,'r')
return json.load(open_file.read())
This is pretty old, but I happened on it looking for something else.
Oddly you never got a direct, obvious, answer -- you want the parent property:
from pathlib import Path
file = Path.cwd().parent / 'data' / 'sales.csv'
Note that some of the answers that say you want __file__ rather than the current working directory may be correct (depending on your use case), in which case it's:
from pathlib import Path
file = Path(__file__).parent.parent / 'data' / 'sales.csv'
(parent of the python file is the code dir, parent of that is the projects dir.
However, It's not great practice to refer to your data by its relative path to your code -- I think using the cwd is a better option -- though what you should do is pass the path to the data in to the script via sys.argv.

Importing classes that contain file paths to read

I have the following file structure:
app/
data/
data.csv
module/
__init__.py
script.py
__init__.py
config.py
My config class contains a set of Pandas dataframes read in from csv files. These dataframes are used across my code base:
import pandas as pd
class Config:
data = pd.read_csv('data/data.csv')
data2 = pd.read_csv('data/data2.csv')
My script contains:
from config import Config
Which returns:
FileNotFoundError: File b'data/data.csv' does not exist
if the run.py script is stored anywhere but the top level.
Is there any way to have class that has some stored file paths without causing a file not found error if importing the class in different scripts across the code base?
Try to specify the file in path resolved by the current file. For example, if your app/config.py is this:
import pandas as pd
class Config:
data = pd.read_csv('data/data.csv')
data2 = pd.read_csv('data/data2.csv')
You want to write the path like this:
mydir = os.path.dirname(os.path.abspath(__file__))
data = pd.read_csv(os.path.join(mydir, 'data/data.csv'))
data2 = pd.read_csv(os.path.join(mydir, 'data/data2.csv'))
which __file__ is the magic variable in Python to tell you which file you're in.
Basically, whenever your script try to open a file, it is relative to your current directory. Therefore, you need the above trick to find the file relative to the script's directory instead of current dir.

Import an entire folder in Python

I've succeeding in importing a single file, but the file calls other files and I get an error. So I'm trying to import and entire folder. I would prefer not to import each file one by one since I know it must be possible to import the whole folder. Here is the syntax I used to import a file:
import importlib.machinery
import os
temp_directory2 = '/Users/me/PycharmProjects/inference_engine2/inference2/ancient/temp.py'
temp_directory = '/Users/me/PycharmProjects/inference_engine2/inference2/Proofs/main_loop.py'
main_directory = '/Users/me/PycharmProjects/inference_engine2/inference2/Proofs/'
b = os.path.exists(temp_directory)
loader = importlib.machinery.SourceFileLoader('temp', temp_directory)
handle = loader.load_module('temp')
You can add the path to the list sys.path at the beginning of your file, like so:
import sys; sys.path.insert(0, r'C:/Users/me/PycharmProjects/inference_engine2/inference2/Proofs')
Note since you are inserting the path at the beginning of the list, this is the first place python will go to look for a module.
Convert it to a package using __init__.py. more here : https://docs.python.org/2/tutorial/modules.html

Categories

Resources