Python OS.PATH : why abspath changing value? - python

I use the very usefull OS library for IT automation.
Bellow the code to create a folder / move into the folder / create a file
import os
# create a directory
os.mkdir("directory")
# get the path of the directory
path = os.path.abspath("directory")
print(f"path after creating the directory: {path}")
# change current directory
os.chdir("directory")
path = os.path.abspath("directory")
print(f"path after changing current directory: {path}")
# create a file
with open("hello.py", "w"):
pass
oupput:
path after creating the directory: P:\Code\Python\directory
path after changing current directory: P:\Code\Python\directory\directory
I don't understand something:
Why the path of the directory file is changing?
I don't have any directory into \directory
Thanks for your answers

If you read the documentation of the [abspath][1] function, you would understand why the extra directory is coming.
Return a normalized absolutized version of the pathname path. On most platforms, this is equivalent to calling the function normpath() as follows: normpath(join(os.getcwd(), path)).
Basically, os.path.abspath('directory') is giving you "the absolute path of something named 'directory' inside the current directory (which also happens to be called 'directory') would be"
The absolute path you're seeing is for something inside the directory you just created, something that doesn't yet exist. The absolute path of the directory you created is stil unchanged, you can check that with:
os.path.abspath('.') # . -> current directory, is the one you created

os.path.abspath translates a the name of a file specified relative to your current working directory, however, the file does not necessarily exist.
So the first call of abpath:
# get the path of the directory
path = os.path.abspath("directory")
print(f"path after creating the directory: {path}")
does nothing more than putting your current working directory in front of the string "directory", you can easily do this by yourself:
os.getcwd() + '/' + "directory"
If you change your working directory with os.chdir("directory") the os.getcwd() returns P:\Code\Python\directory, and appends the second "\directory" to the path. Here you see, that the file does not have to exist.

Related

Checking if a folder is in the current directory

I want to check if there exist a folder in the current folder my code is in, how can this be done?
What I mean is, we have folder called code_folder, which has the python code, i want to check in this python code if in this code_folder we have another folder called folder_1, if is it exists we can store something in it, if not we creat the folder and store something in it.
try this code
import os
path = "code_folder"
# Check whether the defined path exists or not
if not os.path.exists(path):
# Create a new directory
os.makedirs(path)
print("The new directory is created!")
else:
pass
You can use pathlib for this.
if pathlib.Path("path/to/code_folder/folder_1").isdir():
print("the directory exists")
But really, you don't need to check anything, you can just use the exists_ok argument of Path.mkdir, so just:
pathlib.Path("path/to/code_folder/foler_1").mkdir(exists_ok=True)

Hi. I'd like to ask a question about directory in python [duplicate]

This question already has answers here:
How do you properly determine the current script directory?
(16 answers)
How to know/change current directory in Python shell?
(7 answers)
Closed 5 years ago.
How do I determine:
the current directory (where I was in the shell when I ran the Python script), and
where the Python file I am executing is?
To get the full path to the directory a Python file is contained in, write this in that file:
import os
dir_path = os.path.dirname(os.path.realpath(__file__))
(Note that the incantation above won't work if you've already used os.chdir() to change your current working directory, since the value of the __file__ constant is relative to the current working directory and is not changed by an os.chdir() call.)
To get the current working directory use
import os
cwd = os.getcwd()
Documentation references for the modules, constants and functions used above:
The os and os.path modules.
The __file__ constant
os.path.realpath(path) (returns "the canonical path of the specified filename, eliminating any symbolic links encountered in the path")
os.path.dirname(path) (returns "the directory name of pathname path")
os.getcwd() (returns "a string representing the current working directory")
os.chdir(path) ("change the current working directory to path")
Current working directory: os.getcwd()
And the __file__ attribute can help you find out where the file you are executing is located. This Stack Overflow post explains everything: How do I get the path of the current executed file in Python?
You may find this useful as a reference:
import os
print("Path at terminal when executing this file")
print(os.getcwd() + "\n")
print("This file path, relative to os.getcwd()")
print(__file__ + "\n")
print("This file full path (following symlinks)")
full_path = os.path.realpath(__file__)
print(full_path + "\n")
print("This file directory and name")
path, filename = os.path.split(full_path)
print(path + ' --> ' + filename + "\n")
print("This file directory only")
print(os.path.dirname(full_path))
The pathlib module, introduced in Python 3.4 (PEP 428 — The pathlib module — object-oriented filesystem paths), makes the path-related experience much much better.
pwd
/home/skovorodkin/stack
tree
.
└── scripts
├── 1.py
└── 2.py
In order to get the current working directory, use Path.cwd():
from pathlib import Path
print(Path.cwd()) # /home/skovorodkin/stack
To get an absolute path to your script file, use the Path.resolve() method:
print(Path(__file__).resolve()) # /home/skovorodkin/stack/scripts/1.py
And to get the path of a directory where your script is located, access .parent (it is recommended to call .resolve() before .parent):
print(Path(__file__).resolve().parent) # /home/skovorodkin/stack/scripts
Remember that __file__ is not reliable in some situations: How do I get the path of the current executed file in Python?.
Please note, that Path.cwd(), Path.resolve() and other Path methods return path objects (PosixPath in my case), not strings. In Python 3.4 and 3.5 that caused some pain, because open built-in function could only work with string or bytes objects, and did not support Path objects, so you had to convert Path objects to strings or use the Path.open() method, but the latter option required you to change old code:
File scripts/2.py
from pathlib import Path
p = Path(__file__).resolve()
with p.open() as f: pass
with open(str(p)) as f: pass
with open(p) as f: pass
print('OK')
Output
python3.5 scripts/2.py
Traceback (most recent call last):
File "scripts/2.py", line 11, in <module>
with open(p) as f:
TypeError: invalid file: PosixPath('/home/skovorodkin/stack/scripts/2.py')
As you can see, open(p) does not work with Python 3.5.
PEP 519 — Adding a file system path protocol, implemented in Python 3.6, adds support of PathLike objects to the open function, so now you can pass Path objects to the open function directly:
python3.6 scripts/2.py
OK
To get the current directory full path
>>import os
>>print os.getcwd()
Output: "C :\Users\admin\myfolder"
To get the current directory folder name alone
>>import os
>>str1=os.getcwd()
>>str2=str1.split('\\')
>>n=len(str2)
>>print str2[n-1]
Output: "myfolder"
Pathlib can be used this way to get the directory containing the current script:
import pathlib
filepath = pathlib.Path(__file__).resolve().parent
If you are trying to find the current directory of the file you are currently in:
OS agnostic way:
dirname, filename = os.path.split(os.path.abspath(__file__))
If you're using Python 3.4, there is the brand new higher-level pathlib module which allows you to conveniently call pathlib.Path.cwd() to get a Path object representing your current working directory, along with many other new features.
More info on this new API can be found here.
To get the current directory full path:
os.path.realpath('.')
Answer to #1:
If you want the current directory, do this:
import os
os.getcwd()
If you want just any folder name and you have the path to that folder, do this:
def get_folder_name(folder):
'''
Returns the folder name, given a full folder path
'''
return folder.split(os.sep)[-1]
Answer to #2:
import os
print os.path.abspath(__file__)
I think the most succinct way to find just the name of your current execution context would be:
current_folder_path, current_folder_name = os.path.split(os.getcwd())
If you're searching for the location of the currently executed script, you can use sys.argv[0] to get the full path.
For question 1, use os.getcwd() # Get working directory and os.chdir(r'D:\Steam\steamapps\common') # Set working directory
I recommend using sys.argv[0] for question 2 because sys.argv is immutable and therefore always returns the current file (module object path) and not affected by os.chdir(). Also you can do like this:
import os
this_py_file = os.path.realpath(__file__)
# vvv Below comes your code vvv #
But that snippet and sys.argv[0] will not work or will work weird when compiled by PyInstaller, because magic properties are not set in __main__ level and sys.argv[0] is the way your executable was called (it means that it becomes affected by the working directory).

os.path.abspath from where is executed

a newby Python dev here.
I have a json file in the root project folder /json
I´m using os.path.abspath to obtain the absolute path.
abspath = os.path.abspath("json/quotes.json")
But it seems that depending from which class I execute that code is getting the path since that part.
So running my server, the absolute path return
******/app/resources/json/quotes.json'
And if I try from my unit test
*******/tests/json/quotes.json'
What I'm missing here?
Regards
The path to the file is relative to the location of script being executed.
In your case:
abspath = os.path.abspath("json/quotes.json")
is equivalent to:
abspath = os.path.join(os.getcwd(), "json/quotes.json")
The file may not be present at that location and attempting to open it may result in an error.
You could use an environment variable to set a base path and then use this in your script.
# Set a default in an environment variable
if not os.getenv('BASE_PATH'):
os.environ['BASE_PATH'] = '/path/to/base'
# Use the environment variable
abspath = os.path.join(os.getenv('BASE_PATH'), "json/quotes.json")

Why does the path to a file in another dir start sometimes with "./" and sometimes with "../"

I have a file structure that looks like this:
-Project
-trainingData
- Folder1
- Folder2
-python
- get_files.py
-train_model.py
If I want to iterate over each folder in my folder trainingData I use the following function:
data = os.listdir(path_data)
for folder in data:
# Do sth
path_data is "../training_data" in this case. Which makes sense because I need to go one level up and then into the trainingData folder. In cmd I would also type "cd .." and then "cd trainingData"
But why is the path "./training_data" when I call the function in get_files.py from train_model.py. This does not make sense to me. Isn't the relativ path still the same if I would call the function in get_files.py from the file itself?
Because the path is relative to the python file being executed. in this case. train_model.py
The relative path is from the __main__ script, in this case train_model.py. If this wasn't the case then every library or script you imported could all have different relative paths and things would get screwy quickly.
why is the path "./training_data" when I call the function in get_files.py from train_model.py
Because you are calling the file from train_model.py hence the relative path is changed (relative to the current running file).
In order to check the Absolute Path you can use os.path.abspath or os.path.realpath.
Also the newest Path.resolve:
Make the path absolute, resolving any symlinks. A new path object is returned:

How to get the directory to open a file from another file in Python

Having this directory structure. fileOpener.py opens the testfile.txt. And fileCallingFileOpener.py, fileCallingFileOpener2.py and fileCallingFileOpener3.py call a method from fileOpener.py that opens testfile.txt. What would be the correct path written in fileOpener.py so that it always work? Even in other computers.
\parentDirectory
\subfldr1
-fileOpener.py
-testfile.txt
\subfldr2
-fileCallingFileOpener.py
\subfldr2
-fileCallingFileOpener2.py
-fileCallingFileOpener3.py
I am asking something like:
os.path.join("..", "subfldr1", "testfile.txt")
But make it generic so it doesn't depends from where you call it.
You could try to get the location of the fileOpener module using __file__ and then make the path relative to that:
# parentDirectory/subfldr1/fileOpener.py
from pathlib import Path
def read_file():
file_path = Path(__file__).parent / "testfile.txt"
with file_path.open("r", encoding="utf-8") as file:
...
An alternative is to just use an absolute path to a file created in a temp directory, if necessary, or configurable by the end user with, for example, an environment variable.

Categories

Resources