I am having this problem when sharing files with my friends...
I have windows, some use mac and others Linux. When I share python files that contain commands of creating directories, like for instance:
Path_Results = os.path.dirname(Path_Definition)+'\Results'
the directory is not created because in Windows \ is used, whereas in mac and linux / are used.
Any ideas how can I create a more general script ?
Thanks in advance
Use pathlib.Path. Then you'll stop concerning yourself with / or \
On Windows:
>>> from pathlib import Path
>>> updir = Path("..")
>>> resdir = updir / "Result"
>>> resdir
WindowsPath('../Result')
>>> str(resdir)
'..\\Result'
On Linux, Mac, BSD, and other *nix:
>>> from pathlib import Path
>>> updir = Path("..")
>>> resdir = updir / "Result"
>>> resdir
PosixPath('../Result')
>>> str(resdir)
'../Result'
Nearly all stdlib modules and functions accept Path as is, no need to str() it. Example:
from pathlib import Path
resdir = Path("../Result")
filepath = resdir / "somefilename.txt"
assert isinstance(filepath, Path)
with open(filepath, "rt") as fin:
for ln in fin:
# do things
Provided there's a file ..\Result\somefilename.txt (in Windows) or ../Result/somefilename.txt (in Linux/Mac/BSD), the code will work exactly the same.
Edit: For your particular code:
from pathlib import Path
...
# Assuming `Path_Definition` is not a Path object
Path_Results = Path(Path_Definition) / 'Results'
os.sep exists for this very purpose. You can also use os.path.join.
Its not good idea to use '/' or '' directly. path separator mentioned by #mrks is what we need to use.
Related
This is my code
path = r'C:/Users/user/documents/data'
def new_name(path, keyword, ext="csv"):
return ('\\'.join(path.split("\\")[:-1]) + "\\" + path.split("\\")[-1].split(".")[0] + keyword + "." + ext)
new_path = new_name(path, '_test')
print(new_path)
>>> \C:/Users/user/documents/data_test.csv # Output
C:/Users/user/documents/data_test.csv # What I want
I get a path with a file and I would like to add a keyword to this file. Does this option also exist with Pathlib (or something like that)?
Since this path doesn't work properly on Mac, I would like to build a more universal solution.
The pathlib module (Python 3.4+) is your friend when working with paths in Python.
In special, the class pathlib.Path:
This class represents concrete paths of the system’s path flavour (instantiating it creates either a PosixPath or a WindowsPath).
Which means that you don't have to worry about OS-specific path details such as forward/backward slashes.
So the above example could be rewritten as:
from pathlib import Path
path = Path('C:/Users/user/documents/data')
def new_name(path, keyword, ext="csv"):
return Path(str(path) + keyword + '.' + ext)
new_path = new_name(path, '_test')
print(new_path)
>>> C:/Users/user/documents/data_test.csv
I'd use the os.path.join command in this case
for example:
Assume you are running a script from *C:\temp*
and want to load "file_name=inputfile.json" from ./json folder.
You need to concatenate the paths to get one absolute path to the filename: C:\temp\json\inputfile.json
Code would look like:
from os import path
file_name = "inpoutfile.json"
abs_file_path = os.path.join(os.path.dirname(__file__),"json", file_name)
print (abs_file_path)
result is:
C:\temp\json\inputfile.json
I have a list of paths that looks like this C:/Users/myuser/Documents/files\my_file_1.csv and I want to get the file name from that by doing this:
path=['C:/Users/myuser/Documents/files\my_file_1.csv','C:/Users/myuser/Documents/files\my_file_2.csv',...]
filename, file_extension = os.path.splitext(path[0])
and I always get 'C:/Users/myuser/Documents/files\my_file_1' I know it must be for the ' \ ' slash but I haven't been able to replace it. Can anyone give me an idea ?
You can use os.path.basename to get just the filename without the full directory, then os.path.splitext to remove the file extension.
>>> import os
>>> [os.path.splitext(os.path.basename(i))[0] for i in path]
['my_file_1', 'my_file_2']
Or if you want the filename and extension, but no directories
>>> [os.path.basename(i) for i in path]
['my_file_1.csv', 'my_file_2.csv']
As you are using windows and if you are using python 3.4+
>>> from pathlib import PureWindowsPath
>>> path=['C:/Users/myuser/Documents/files\my_file_1.csv','C:/Users/myuser/Documents/files\my_file_2.csv']
>>> print([PureWindowsPath(i).name for i in path])
['my_file_1.csv', 'my_file_2.csv']
I need to extract the name of the parent directory of a certain path. This is what it looks like:
C:\stuff\directory_i_need\subdir\file.jpg
I would like to extract directory_i_need.
import os
## first file in current dir (with full path)
file = os.path.join(os.getcwd(), os.listdir(os.getcwd())[0])
file
os.path.dirname(file) ## directory of file
os.path.dirname(os.path.dirname(file)) ## directory of directory of file
...
And you can continue doing this as many times as necessary...
Edit: from os.path, you can use either os.path.split or os.path.basename:
dir = os.path.dirname(os.path.dirname(file)) ## dir of dir of file
## once you're at the directory level you want, with the desired directory as the final path node:
dirname1 = os.path.basename(dir)
dirname2 = os.path.split(dir)[1] ## if you look at the documentation, this is exactly what os.path.basename does.
For Python 3.4+, try the pathlib module:
>>> from pathlib import Path
>>> p = Path('C:\\Program Files\\Internet Explorer\\iexplore.exe')
>>> str(p.parent)
'C:\\Program Files\\Internet Explorer'
>>> p.name
'iexplore.exe'
>>> p.suffix
'.exe'
>>> p.parts
('C:\\', 'Program Files', 'Internet Explorer', 'iexplore.exe')
>>> p.relative_to('C:\\Program Files')
WindowsPath('Internet Explorer/iexplore.exe')
>>> p.exists()
True
All you need is parent part if you use pathlib.
from pathlib import Path
p = Path(r'C:\Program Files\Internet Explorer\iexplore.exe')
print(p.parent)
Will output:
C:\Program Files\Internet Explorer
Case you need all parts (already covered in other answers) use parts:
p = Path(r'C:\Program Files\Internet Explorer\iexplore.exe')
print(p.parts)
Then you will get a list:
('C:\\', 'Program Files', 'Internet Explorer', 'iexplore.exe')
Saves tone of time.
First, see if you have splitunc() as an available function within os.path. The first item returned should be what you want... but I am on Linux and I do not have this function when I import os and try to use it.
Otherwise, one semi-ugly way that gets the job done is to use:
>>> pathname = "\\C:\\mystuff\\project\\file.py"
>>> pathname
'\\C:\\mystuff\\project\\file.py'
>>> print pathname
\C:\mystuff\project\file.py
>>> "\\".join(pathname.split('\\')[:-2])
'\\C:\\mystuff'
>>> "\\".join(pathname.split('\\')[:-1])
'\\C:\\mystuff\\project'
which shows retrieving the directory just above the file, and the directory just above that.
import os
directory = os.path.abspath('\\') # root directory
print(directory) # e.g. 'C:\'
directory = os.path.abspath('.') # current directory
print(directory) # e.g. 'C:\Users\User\Desktop'
parent_directory, directory_name = os.path.split(directory)
print(directory_name) # e.g. 'Desktop'
parent_parent_directory, parent_directory_name = os.path.split(parent_directory)
print(parent_directory_name) # e.g. 'User'
This should also do the trick.
This is what I did to extract the piece of the directory:
for path in file_list:
directories = path.rsplit('\\')
directories.reverse()
line_replace_add_directory = line_replace+directories[2]
Thank you for your help.
You have to put the entire path as a parameter to os.path.split. See The docs. It doesn't work like string split.
If I have an opened file, is there an os call to get the complete path as a string?
f = open('/Users/Desktop/febROSTER2012.xls')
From f, how would I get "/Users/Desktop/febROSTER2012.xls" ?
The key here is the name attribute of the f object representing the opened file. You get it like that:
>>> f = open('/Users/Desktop/febROSTER2012.xls')
>>> f.name
'/Users/Desktop/febROSTER2012.xls'
Does it help?
I had the exact same issue. If you are using a relative path os.path.dirname(path) will only return the relative path. os.path.realpath does the trick:
>>> import os
>>> f = open('file.txt')
>>> os.path.realpath(f.name)
And if you just want to get the directory name and no need for the filename coming with it, then you can do that in the following conventional way using os Python module.
>>> import os
>>> f = open('/Users/Desktop/febROSTER2012.xls')
>>> os.path.dirname(f.name)
>>> '/Users/Desktop/'
This way you can get hold of the directory structure.
You can get it like this also.
filepath = os.path.abspath(f.name)
Suppose my python code is executed a directory called main and the application needs to access main/2091/data.txt.
how should I use open(location)? what should the parameter location be?
I found that below simple code will work.. does it have any disadvantages?
file = "\2091\sample.txt"
path = os.getcwd()+file
fp = open(path, 'r+');
With this type of thing you need to be careful what your actual working directory is. For example, you may not run the script from the directory the file is in. In this case, you can't just use a relative path by itself.
If you are sure the file you want is in a subdirectory beneath where the script is actually located, you can use __file__ to help you out here. __file__ is the full path to where the script you are running is located.
So you can fiddle with something like this:
import os
script_dir = os.path.dirname(__file__) #<-- absolute dir the script is in
rel_path = "2091/data.txt"
abs_file_path = os.path.join(script_dir, rel_path)
This code works fine:
import os
def read_file(file_name):
file_handle = open(file_name)
print file_handle.read()
file_handle.close()
file_dir = os.path.dirname(os.path.realpath('__file__'))
print file_dir
#For accessing the file in the same folder
file_name = "same.txt"
read_file(file_name)
#For accessing the file in a folder contained in the current folder
file_name = os.path.join(file_dir, 'Folder1.1/same.txt')
read_file(file_name)
#For accessing the file in the parent folder of the current folder
file_name = os.path.join(file_dir, '../same.txt')
read_file(file_name)
#For accessing the file inside a sibling folder.
file_name = os.path.join(file_dir, '../Folder2/same.txt')
file_name = os.path.abspath(os.path.realpath(file_name))
print file_name
read_file(file_name)
I created an account just so I could clarify a discrepancy I think I found in Russ's original response.
For reference, his original answer was:
import os
script_dir = os.path.dirname(__file__)
rel_path = "2091/data.txt"
abs_file_path = os.path.join(script_dir, rel_path)
This is a great answer because it is trying to dynamically creates an absolute system path to the desired file.
Cory Mawhorter noticed that __file__ is a relative path (it is as well on my system) and suggested using os.path.abspath(__file__). os.path.abspath, however, returns the absolute path of your current script (i.e. /path/to/dir/foobar.py)
To use this method (and how I eventually got it working) you have to remove the script name from the end of the path:
import os
script_path = os.path.abspath(__file__) # i.e. /path/to/dir/foobar.py
script_dir = os.path.split(script_path)[0] #i.e. /path/to/dir/
rel_path = "2091/data.txt"
abs_file_path = os.path.join(script_dir, rel_path)
The resulting abs_file_path (in this example) becomes: /path/to/dir/2091/data.txt
It depends on what operating system you're using. If you want a solution that is compatible with both Windows and *nix something like:
from os import path
file_path = path.relpath("2091/data.txt")
with open(file_path) as f:
<do stuff>
should work fine.
The path module is able to format a path for whatever operating system it's running on. Also, python handles relative paths just fine, so long as you have correct permissions.
Edit:
As mentioned by kindall in the comments, python can convert between unix-style and windows-style paths anyway, so even simpler code will work:
with open("2091/data/txt") as f:
<do stuff>
That being said, the path module still has some useful functions.
I spend a lot time to discover why my code could not find my file running Python 3 on the Windows system. So I added . before / and everything worked fine:
import os
script_dir = os.path.dirname(__file__)
file_path = os.path.join(script_dir, './output03.txt')
print(file_path)
fptr = open(file_path, 'w')
Try this:
from pathlib import Path
data_folder = Path("/relative/path")
file_to_open = data_folder / "file.pdf"
f = open(file_to_open)
print(f.read())
Python 3.4 introduced a new standard library for dealing with files and paths called pathlib. It works for me!
Code:
import os
script_path = os.path.abspath(__file__)
path_list = script_path.split(os.sep)
script_directory = path_list[0:len(path_list)-1]
rel_path = "main/2091/data.txt"
path = "/".join(script_directory) + "/" + rel_path
Explanation:
Import library:
import os
Use __file__ to attain the current script's path:
script_path = os.path.abspath(__file__)
Separates the script path into multiple items:
path_list = script_path.split(os.sep)
Remove the last item in the list (the actual script file):
script_directory = path_list[0:len(path_list)-1]
Add the relative file's path:
rel_path = "main/2091/data.txt
Join the list items, and addition the relative path's file:
path = "/".join(script_directory) + "/" + rel_path
Now you are set to do whatever you want with the file, such as, for example:
file = open(path)
import os
def file_path(relative_path):
dir = os.path.dirname(os.path.abspath(__file__))
split_path = relative_path.split("/")
new_path = os.path.join(dir, *split_path)
return new_path
with open(file_path("2091/data.txt"), "w") as f:
f.write("Powerful you have become.")
If the file is in your parent folder, eg. follower.txt, you can simply use open('../follower.txt', 'r').read()
Get the path of the parent folder, then os.join your relative files to the end.
# get parent folder with `os.path`
import os.path
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
# now use BASE_DIR to get a file relative to the current script
os.path.join(BASE_DIR, "config.yaml")
The same thing with pathlib:
# get parent folder with `pathlib`'s Path
from pathlib import Path
BASE_DIR = Path(__file__).absolute().parent
# now use BASE_DIR to get a file relative to the current script
BASE_DIR / "config.yaml"
Python just passes the filename you give it to the operating system, which opens it. If your operating system supports relative paths like main/2091/data.txt (hint: it does), then that will work fine.
You may find that the easiest way to answer a question like this is to try it and see what happens.
Not sure if this work everywhere.
I'm using ipython in ubuntu.
If you want to read file in current folder's sub-directory:
/current-folder/sub-directory/data.csv
your script is in current-folder
simply try this:
import pandas as pd
path = './sub-directory/data.csv'
pd.read_csv(path)
When I was a beginner I found these descriptions a bit intimidating. As at first I would try
For Windows
f= open('C:\Users\chidu\Desktop\Skipper New\Special_Note.txt','w+')
print(f)
and this would raise an syntax error. I used get confused alot. Then after some surfing across google. found why the error occurred. Writing this for beginners
It's because for path to be read in Unicode you simple add a \ when starting file path
f= open('C:\\Users\chidu\Desktop\Skipper New\Special_Note.txt','w+')
print(f)
And now it works just add \ before starting the directory.
In Python 3.4 (PEP 428) the pathlib was introduced, allowing you to work with files in an object oriented fashion:
from pathlib import Path
working_directory = Path(os.getcwd())
path = working_directory / "2091" / "sample.txt"
with path.open('r+') as fp:
# do magic
The with keyword will also ensure that your resources get closed properly, even if you get something goes wrong (like an unhandled Exception, sigint or similar)