I have the following project structure
SampleProject
com
python
example
source
utils
ConfigManager.py
conf
constants.cfg
How to access constants.cfg from ConfigManager.py.
I have a limitation
- I can not give full path(absolute path) of constants.cfg because if I run in different PC it should work with out any modification
Also if I represent something like below, I can access the file. But I don't want to give back slash every time
filename = ..\\..\\..\\..\\..\\..\\constants.cfg`
Currently I am doing something like this. But this works only when constants.cfg and ConfigManager.py are in same directory
currentDir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
file = open(os.path.join(currentDir,'constants.cfg'))
If conf
is a Python package then you could use pkgutil.get_data()
:
import pkgutil
data = pkgutil.get_data("conf", "constants.cfg")
Or if setuptools
is installed – pkg_resources.resource_string()
:
import pkg_resources
data = pkg_resources.resource_string('conf', 'constants.cfg')
If constants.cfg
is not in a package then pass its path as a command-line parameter, or set it in an environment variable e.g., CONFIG_MANAGER_CONSTANTS_PATH
, or read from a fixed set of default paths e.g., os.path.expanduser("~/.config/ConfigManager/constants.cfg")
. To find a place where to put user data, you could use appdirs
module.
You can't use os.getcwd()
that returns current working directory if you may run ConfigManager.py
from different directories. Relative path "../../..."
won't work for the same reason.
If you are certain that the relative position of ConfigManager.py
and constants.cfg
in the filesystem won't change:
import inspect
import os
import sys
def get_my_path():
try:
filename = __file__ # where we were when the module was loaded
except NameError: # fallback
filename = inspect.getsourcefile(get_my_path)
return os.path.realpath(filename)
# path to ConfigManager.py
cm_path = get_my_path()
# go 6 directory levels up
sp_path = reduce(lambda x, f: f(x), [os.path.dirname]*6, cm_path)
constants_path = os.path.join(sp_path, "conf", "constants.cfg")
If you had some module in the root of the project tree, say config_loader.py that looked like this:
import os
def get_config_path():
relative_path = 'conf/constants.cfg'
current_dir = os.getcwd()
return os.join(current_dir, relative_path)
And then in ConfigManager.py or any other module that needs the configs:
import config_loader
file_path = config_loader.get_config_path()
config_file = open(file_path)
You could even have your config_loader.py just return the config file.
You can use the pathlib package in Python 3.0+
This gets the path to any file contained in the SampleProject folder
across different platforms.
from pathlib import Path
def get_file(path):
"""
returns the absolute path of a file
:var
str path
the file path within the working dir
:returns
PureWindowsPath or PurePosixPath object
type depends on the operating system in use
"""
def get_project_root() -> Path:
"""Returns project root folder."""
return Path(__file__).parent.parent
return get_project_root().joinpath(path)
Then simply call the function with the file_path as an argument:
filePath = get_file('com/python/example/source/utils/configManager.py')
And then the usual procedure:
while open(filePath) as f:
<DO YOUR THING>