os.path.abspath is not producing the absolute path for the directory python - python-3.x

its a simple program which outputs the full file path using a given path that does not include the root. But It just prints out the given path. why?
operating system Ubutu18.04 Lts, IDE Pycharm , python 3.7
I've tried installing pathlib and path.py but it still does not work.
from os.path import abspath, relpath
x = '/python/100 exercises/24.py'
print(abspath(x))
The expected output is
/home/tasif/Documents/python/100 exercises/24.py
actual result is
/python/100 exercises/24.py

By putting a / at the beginning of your path, your system is interpreting x as a root system path already. Instead, write your path as x = 'python/100 exercises/24.py' and try again.

I think this is true but I could be corrected: You need to run it as os.path.abspath(x) otherwise the script does not know where to get that function from and is doing nothing but printing your string with a non-function ran on it.
You should also rename your directory to 100_exercises/ or something more posix friendly.

Related

Import module (not file) from a different path

I am trying to import a module (not a file) from a different path.
By module, I mean that I have a folder named Util containing a single file named __init__.py.
Using import Util in a python file on the same level as the Util folder works fine.
But this is not the case when the python file resides elsewhere.
Following this answer, I have this piece of code working:
import sys,os
sys.path.append(os.path.dirname(__file__)+'the relative path to the python file that I want to import')
But it works only when I import a python file, not a python module.
How can I resolve this?
Problem solved:
Due to the fact that I am using Windows, the string os.path.dirname(__file__)+'the relative path to the python file that I want to import' contains a mixture of forward slashes (/) and backward slashes (\).
The simple solution is to ensure that the (OS-dependent) expression os.path.dirname(__file__) contains only forward slashes:
os.path.dirname(__file__).replace('\\','/')
Same goes for the constant part 'the relative path to the python file that I want to import' of course, which one can simply fix manually if needed (I already had this one with forward slashes only).

Import a python module from within a packed module

So I builded a python package localy:
cgi#cgires:~$ pip list | grep mads
madscgi 0.1.0
Its nice! Afterwards I can use it in Jupyter Notebook, in iPython Shell, in Python Shell and even in python scripts outside the modules code. So it works as expected 100% outside the modules code:
Thats nice, but next I want to import code from one builded module (inside the package) into another python file (inside the package). Lets name it import_test.py and try it out:
So it fails if it is getting executed in the directory, where the package is build from. And it looks like, that the python interpreter is taking the parent directory (with the same name like the module) and this is failing.
Is is possible to enforce the usage of the installed pip-package?
As #MisterMiyagi pointed out, the problem was, that there were an upper folder which had the same name as the module.
Here: mads_cons is the upper folder from import_test.py. Therefore, the upper folder is getting imported instead of the via pip installed module. Thats it.
The file you want to import should either be in the same folder or referred to with the absolute path of it.
If that doesn't suit you, you can call sys.path
import sys
sys.path
You can keep your file in any of the directories sys.path returns.
Smart would be, if you keep the file inside.
......../site-packages/

Imports using PyCharm don't work on command line

I'm a bit new to Python and I'm building a project in PyCharm since I'm used to IntelliJ, and have a problem with my file structure. When I need to import a file in the same subdirectory-- directory c, I have to type
from a.b.c import y where a is the project's home directory b.c is the sub directory I'm in.
So I'm not able to import y directory. Which this then causes a problem if I want to run this file via command line, it uses the current directory as the path, meaning the import doesn't know anything about x.xx. What can I do to fix this issue?
Thanks!
For the purposes of this answer I'm assuming y is a Python module in the c directory. In other words there is a file called y.py in a/b/c.
import y works in a Python module in directory c if the current working directory is also c.
In Intellij IDEA with the Python plugin (much the same as PyCharm most of the time) the current working directory is called the "Working Directory" in each Run/Debug configuration you set up to run your script.
import y will also work if c is on the PYTHONPATH.
The other way to make y available to the import statement is to turn a and b directories into Python packages. That means at least putting an empty __init__.py file in both the a and b directories.
You can then use a as the root directory for the project, and use:
from a.b.c import y
It's worth reading The Definitive Guide to Python import Statements if you're not sure how Python resolves imports.

How to get absolute pyc file path with python 3.x?

How can we get the compiled python pyc file path with python 3.x in the current environment? I know it's in the __pycache__ direcotry, but I couldn't find a way to find the file path. Because the names of pyc files of python 3 changes by the environment.
Given that you know the path to the source (ie .py) file, there's a function importlib.util.cache_from_source that does exactly what you want. For example, to get the .pyc file corresponding to the numpy package, you would do:
import importlib
import numpy
importlib.util.cache_from_source(numpy.__file__)
For me (on OS X), this prints out something along the lines of:
/<absolute path to site-packages>/numpy/__pycache__/__init__.cpython-36.pyc

__file__ does not exist in Jupyter Notebook

I'm on a Jupyter Notebook server (v4.2.2) with Python 3.4.2 and
I want to use the global name __file__, because the notebook will be cloned from other users and in one section I have to run:
def __init__(self, trainingSamplesFolder='samples', maskFolder='masks'):
self.trainingSamplesFolder = self.__getAbsPath(trainingSamplesFolder)
self.maskFolder = self.__getAbsPath(maskFolder)
def __getAbsPath(self, path):
if os.path.isabs(path):
return path
else:
return os.path.join(os.path.dirname(__file__), path)
The __getAbsPath(self, path) checks if a path param is a relative or absolute path and returns the absolute version of path. So I can use the returned path safely later.
But I get the error
NameError: name '__file__' is not defined
I searched for this error online and found the "solution" that I should better use sys.argv[0], but print(sys.argv[0]) returns
/usr/local/lib/python3.4/dist-packages/ipykernel/__main__.py
But the correct notebook location should be /home/ubuntu/notebooks/.
Thanks for the reference How do I get the current IPython Notebook name from Martijn Pieters (comments) the last answer (not accepted) fits perfect for my needs:
print(os.getcwd())
/home/ubuntu/notebooks
If you want to get path of the directory in which your script is running, I would highly recommend using,
os.path.abspath('')
Advantages
It works from Jupyter Notebook
It work from REPL
It doesn't require Python 3.4's pathlib
Please note that one scenario where __file__ has advantage is when you are invoking python from directory A but running script in directory B. In that case above as well as most other methods will return A, not B. However for Jupyter notbook, you always get folder for .ipyn file instead of the directory from where you launched jupyter notebook.
__file__ might not be available for you, but you can get current folder in which your notebook is located in different way, actually.
There are traces in global variables, if you will call globals() you will see that there is an element with the key _dh, that might help you. Here how I managed to load the data.csv file that is located in the same folder as my notebook:
import os
current_folder = globals()['_dh'][0]
# Calculating path to the input data
data_location = os.path.join(current_folder,'data.csv')
In modern Python (v3.4+) we can use pathlib to get the notebook's directory:
from pathlib import Path
cwd = Path().resolve()
# cwd == PosixPath('/path/to/this/jupyter/ipynb/file's/directory/')
# or this way, thanks #NunoAndré:
cwd = Path.cwd()
# cwd == PosixPath('/path/to/this/jupyter/ipynb/file's/directory/')
Update
#ShitalShah I cannot reproduce the error you are reporting. Jupyter notebook seems to work fine, regardless of the current working directory the application was started.
Example: file ~/dir1/dir2/untitled.ipynb and Jupyter notebook started in ~/dir1:
Jupyter notebook started in ~/dir1/dir2:
It's not possible to get the path to the notebook. You may find a way to get it that only works in one environment (eg os.getcwd()), but it won't necessarily work if the notebook is loaded in a different way.
Instead, try to write the notebook so that it doesn't need to know its own path. If doing something like getting the pwd, then be sure to fail fast / print an error if this doesn't work, vs. just silently trying to continue on.
See also: https://github.com/ipython/ipython/issues/10123
I'm new to python, but this works for me.
You can get os.path.dirname(__file__) equivalence by:
sys.path[0]
On new version of python and notebook __file__ works... If you have older versions, to get __file__ you can use
import inspect
from pathlib import Path
module_path = Path(inspect.getframeinfo(inspect.currentframe()).filename).resolve()
But... This is much slower... On the other hand, it will not return currrent working directory, but path to module, even if module is imported from elsewhere.

Resources