There are multiple threads about getting the current Python's script directory, for example:
import os
dir = os.path.dirname(os.path.abspath(__file__))
The question is, what should I do if I want to add this function into some utility file, while I want the returned value to be the directory of the calling file, in this case, the file executed by the user?
What would happen here?
// utils.py
def get_script_dir():
import os
return os.path.dirname(os.path.abspath(__file__))
// main_app.py
from utils import get_script_dir
print(get_script_dir())
// user's shell
python c:\path\to\somewhere\main_app.py
Will it print the directory of main_app.py or the directory of utils.py? What is an elegant solution for placing the function in the utils file while getting the directory of the file that was actually executed by the user?
Please try following and let me know whether it's exactly what you want:
# utils.py
def get_script_dir():
import sys
import os
return os.path.dirname(sys.modules['__main__'].__file__)
# main_app.py
from utils import get_script_dir
print(get_script_dir())
Supposing that your project directory tree is like the following:
Python/
main.py
modules/
utils.py
__init__.py
Being Python/modules/utils.py:
import os
get_script_dir = lambda file: os.path.dirname(os.path.abspath(file))
and Python/main.py:
from modules import utils
import os
script_dir = utils.get_script_dir(__file__)
print("[i] Currently executing file {} located at {}".format(os.path.basename(__file__), script_dir))
Executing Python/main.py is going to output something like:
[i] Currently executing file main.py located at C:\Users\BlackVirusScript\Desktop\Python
Related
How can I get the current path using another file.
Example:
I have the folder structure below:
src
script.py
configs
initial_config.py
In my initial_config.py file I have the code below:
import os
path = os.path.dirname(__file__)
print(path)
#The return of this print is /src/configs
In my script.py I'm trying to import the initial_config file and the return of the print I need it to be the script.py path.
from configs.initial_config import path
print(path)
#The return of this import is /src/configs
How can I return the /src/ path having the os.path function in other file in the simplest way possible?
Turn your logic of finding the path into a function in configs/initial_config.py, then import it from scripts.py:
# configs/initial_config.py
import os
def find_path(file=__file__):
return os.path.dirname(file)
# script.py
from configs.initial_config import find_path
print(find_path(__file__))
I am trying to get a list of the imported custom modules (modules I created by myself) in my current file but I could not find a proper way to achieve it.
For example:
<test.py>
import sys
import foo
import bar
I would like to get a list of [foo, bar] excluding the sys module.
Lets say, that if file located near curent file, or in some subfolder, when it's "our" module, not system one.
For this example, I've created three files: main.py, other.py and another.py, and placed whem into one folder.
The code of main.py is:
# os and sys are needed to work
import sys
import os
import shutil
import io
import datetime
import other
import another
def get_my_modules():
# Get list of modules loaded
modules = list(sys.modules.keys())
mymodules = []
# Get current dir
curdir = os.path.realpath(os.path.dirname(__file__))
for m in modules:
try:
# if some module's file path located in current folder or in some subfolder
# lets sey, that it's our self-made module
path = sys.modules[m].__file__
if path.startswith(curdir):
mymodules.append(m)
except Exception:
# Exception could happen if module doesn't have any __file__ property
pass
# Return list of our moudles
return mymodules
print(get_my_modules())
And this code actually outputs ["other", "another"]
This approach has a problem: If you import module, that somehow located in upper folder, it woudln't be detected.
In my python application, I open mp3 files with relative paths from where the program was started. To keep it simple, I made a minimal reproduction of the problem I have in my project here.
Basically, I have a structure like this:
src
└─ main.py
test
└─ test_main.py
In main.py I have a simple function that prints and returns the current working directory:
def get_cwd() -> str:
directory = os.path.basename(os.getcwd())
print('Current directory =', directory)
return directory
So if I cd into the src folder and run python main.py I see:
Current directory = src
This is the desired behavior, as in my program the file paths to the mp3 files are relative to src.
The problem arises when I try to write tests. I can't seem to get a test like this to pass, no matter what I pass to --start-directory and --top-level-directory:
def test_get_cwd(self):
print('testing get_cwd()')
current_dir = get_cwd()
self.assertIsNotNone(current_dir)
self.assertEqual(current_dir, 'src')
The question: How can I run my tests as if they were running in the context of a specific directory if they are saved to a different directory?
Constraints:
the tests must import using absolute paths, as in my example: from
src.main import get_cwd
There is a os function to change the directory, try adding os.chdir('src') to your test.
import unittest
import os
from src.main import get_cwd
class TestMain(unittest.TestCase):
def test_get_cwd(self):
os.chdir('src')
print('testing get_cwd()')
current_dir = get_cwd()
self.assertIsNotNone(current_dir)
self.assertEqual(current_dir, 'src')
An option is to mock the value given by os.path.basename with a return value of "src"
import unittest
from mock import patch
from src.main import get_cwd
class TestMain(unittest.TestCase):
#patch('os.path.basename')
def test_get_cwd(self, basename):
basename.return_value = "src"
print('testing get_cwd()')
current_dir = get_cwd()
self.assertIsNotNone(current_dir)
self.assertEqual(current_dir, 'src')
My flask application is one big lists of files right now and I am trying to divide it up into two primary folders, app and spiders so that it looks like this:
- app
-- __init__.py
-- app.py
-- models.py
- spiders
-- __init__.py
-- scrape.py
Procfile
requirements.txt
The problem I am having is when trying to import my models into the scrape.py file.
When I try to import it absolutely with:
from app.models import Rate, Hotel, Location I get the error 'no module named app'.
When I try to import relatively:
from ..app.models import Rate, Hotel, Location I get the error SystemError: Parent module '' not loaded, cannot perform relative import.
What can I do to fix this?
This should work:
import sys
from os.path import dirname, abspath, sep
sys.path.append(abspath(dirname(__file__) + sep + ".."))
import app.models as models
Note: This is really an ugly solution as it messes up your import block in the file. I suggest to add a main code file in the root folder like main.py and import spiders and app modules in there. You should not spread your flow controllers among files in sub folders
I have a directory which has all the files:
myDirectory/
directory1/
importantFile.py
Output.py
How can I import Output.py from importantFile.py without having to put in the same directory?
importantFile.py
import Output
Output.write('This worked!')
Output.py
class Output():
def writeOutput(s):
print s
if "call" is import, in Output.py
import sys
import os.path
# change how import path is resolved by adding the subdirectory
sys.path.append(os.path.abspath(os.getcwd()+'/directory1'))
import importantFile
importantFile.f()
sys.path contains the list of path where to look for modules, details in https://docs.python.org/2/library/sys.html
The other way is to use the relative notation, for which the python file you want to import should be in a package.
You have to make the directory a python package by putting an init.py file.
Look for the packages section in this link.
https://docs.python.org/2/tutorial/modules.html
import sys
sys.path.append('/full/path/to/use')
global exist_importedname
exist_importedname = True
try:
import myimport
except ImportError as e:
exist_importedname = False
print (e.message)