What is 'subdir' defined var in python 3 for all OS? - python

I have a script in Python which i get 3 arguments from the user
One of the arguments is a folder path in which there are some files i need to use
Since my program is designed for all OS, i would like to know how to use the path from the argument correctly to get to my required files
I.E.
if i get the following path :
c:\windows
i would like to be able to get 1.exe in this folder,
In windows it will be slash or backslash but in unix systems it will be probably different,
As i understand there is a const or defined var from 'os' module in which i can use as this subdir sign, where can i find it ?
Thank you

Just use os.path.join and Python will take care of the slash for you:
path = os.path.join(sys.argv[1], '1.exe')
The platform-specific path separator is stored as os.sep.

Use os.path.join(). For example:
os.path.join(dirname, "1.exe")

Related

How to resolve a server path on Windows with Pathlib?

So I have a path to a server that looks like
\\foo\bar\baz
I am trying to convert this to a Path object with Python's pathlib library with something like
Path('\\foo').joinpath('bar').joinpath('baz')
Trying to see if this path exists with "path.exists()" however signals that the path doesn't exist.
I have also replace the starting path of the path with the following the same result:
Path(r'\\foo'), Path('\\\\foo'), Path('\foo)
Printing out the path after being parsed by Path appears to show the path being interpreted as, no matter how the foo root is entered
'C:/foo/bar/baz'
However when I simply plop the path in os.path.exists as a raw string, the path is successfully found (using a normal string results in a unicode error)
os.path.exists(r'\\foo\bar\baz')
Is there anyway to use Pathlib in such a way that the server path is successfully parsed / interpreted, or am I forced to just use a raw string with os.path operations?
r'\\foo' is just not a valid windows UNC path, even if foo exists. You need at least a sharename after that.
From Microsoft documentation:
A valid UNC path MUST contain two or more path components.
This creates a valid path object on which exists() will work properly:
>>> pathlib.Path(r'\\foo\bar').joinpath('baz')
WindowsPath('//foo/bar/baz')

How to manipulate directory paths to work across multiple OS?

I'm writing a python script which has to internally create output path from the input path. However, I am facing issues to create the path which I can use irrespective of OS.
I have tried to use os.path.join and it has its own limitations.
Apart from that, I think simple string concatenation is not the way to go.
Pathlib can be an option but I am not allowed to use it.
import os
inputpath = "C:\projects\django\hereisinput"
lastSlash = left.rfind("\\")
# This won't work as os path join stops at a slash
outputDir = os.path.join(left[:lastSlash], "\internal\morelevel\outputpath")
OR
OutDir = left[:lastSlash] + "\internal\morelevel\outputpath"
Expected output path :
C:\projects\django\internal\morelevel\outputpath
Also, the above code doesn't do it OS Specific where in Linux, the slash will be different.
Is os.sep() some option ?
From the documentation os.path.join can join "one or more path components...". So you could split "\internal\morelevel\outputpath" up into each of its components and pass all of them to your os.path.join function instead. That way you don't need to "hard-code" the separator between the path components. For example:
paths = ("internal", "morelevel", "outputpath")
outputDir = os.path.join(left[:lastSlash], *paths)
Remember that the backslash (\) is a special character in Python so your strings containing singular backslashes wouldn't work as you expect them to! You need to escape them with another \ in front.
This part of your code lastSlash = left.rfind("\\") might also not work on any operating system. You could rather use something like os.path.split to get the last part of the path that you need. For example, _, lastSlash = os.path.split(left).
Assuming your original path is "C:\projects\django\hereisinput", your other part of the path as "internal\morelevel\outputpath" (notice this is a relative path, not absolute), you could always move your primary back one folder (or more) and then append the second part. Do note that your first path needs to contain only folders and can be absolute or relative, while your second path must always be relative for this hack to work
path_1 = r"C:\projects\django\hereisinput"
path_2 = r"internal\morelevel\outputpath"
path_1_one_folder_down = os.path.join(path_1, os.path.pardir)
final_path = os.path.join(path_1_one_folder_down, path_2)
'C:\\projects\\django\\hereisinput\\..\\internal\\morelevel\\outputpath'

Passing commands to OS: What is wrong here?

So, I want to create a simple script to create directories based upon the file names contained within a certain folder.
My method looks like this:
def make_new_folders(filenames, destination):
"""
Take a list of presets and create new directories using mkdir
"""
for filename in filenames:
path = '"%s/%s/"' % (destination, filename)
subprocess.call(["mkdir", path])
For some reason I can't get the command to work.
If I pass in a file named "Test Folder", i get an error such as:
mkdir: "/Users/soundteam/Desktop/PlayGround/Test Folder: No such file or directory
Printing the 'path' variable results in:
"/Users/soundteam/Desktop/PlayGround/Test Folder/"
Can anyone point me in the right direction?
First of all, you should use os.path.join() to glue your path parts together because it works cross-platform.
Furthermore, there are built-in commands like os.mkdir or os.makedirs (which is really cool because it's recursive) to create folders. Creating a subprocess is expensive and, in this case, not a good idea.
In your example you're passing double-quotes ("destination/filename") to subprocess, which you don't have to do. Terminals need double-quotes if you use whitespaces in file or folder names, subprocess takes care of that for you.
You don't need the double quotes. subprocess passes the parameters directly to the process, so you don't need to prepare them for parsing by a shell. You also don't need the trailing slash, and should use os.path.join to combine path components:
path = os.path.join(destination, filename)
EDIT: You should accept #Fabian's answer, which explains that you don't need subprocess at all (I knew that).

os.path.join(os.path.dirname(__file__)) returns nothing

I have a directory structure like this:
--bin/
--lib/
--data/
So basically, the executable script is in bin and it calls the files in lib.. but lib has to communicate with the text files in data
Usually this use to work:
TO read a file in usually i use to do this
file_path = os.path.join(os.path.dirname(__file__))+ "/../" +"data/"+filename
f = open(file_path,"r")
But, in this instance, if i do:
print os.path.join(os.path.dirname(__file__))
returns nothing?
What am i doing wrong..
Thanks
I guess with nothing you mean an empty string? This could only be the case, if __file__ was an empty string in the first place. Did you accidentally overwrite __file__?
One other comment in addition to the others...the point of os.path.join is to avoid things like
mypath=dir + '/' + subdir + '/'+filename
This is done much more cleanly using
mypath=os.path.join(dir,subdir,filename) # can have as many arguments as you want!
Also, you can avoid explicit '..' and '.' in path names by using os.pardir and os.curdir. (e.g.)
file_path = os.path.join(os.path.dirname(__file__),os.pardir,'data',filename)
This should increase the portability of your code (and is a good habit to get into even if you don't plan on running this script anywhere else).
It depends on how you start your script, for example:
if /bin/script.py contains:
import os
print os.path.dirname(__file__) #no reason to use os.path.join()
then:
$> python /bin/script.py
/bin
$> cd /bin
$> python script.py
#nothing
$>
It'a a better idea to use the following:
file_path = os.path.abspath(__file__)
and then do whatever you want with that.

Python: How to Access Linux Paths

Using Python, how does one parse/access files with Linux-specific features, like "~/.mozilla/firefox/*.default"? I've tried this, but it doesn't work.
Thanks
This
import glob, os
glob.glob(os.path.expanduser('~/.mozilla/firefox/*.default'))
will give you a list of all files ending in ".default" in the current user's ~/.mozilla/firefox directory using os.path.expanduser to expand the ~ in the path and glob.glob to match the *.default file pattern.
~ is expanded by the shell and not a real path. As such you have to navigate there manually.
import os
homeDir = os.environ['HOME']
f = open( homeDir + '/.mozilla/firefox/*.default' )
# ...
It's important to remember:
use of the tilde ~ expands the home directory as per Poke's answer
use of the forward slash / is the separator for linux / *nix directories
by default, *nix systems such as linux for example has a wild card globbing in the shell, for instance echo *.* will return back all files that match the asterisk dot asterisk (as per Will McCutcheon's answer!)
http://docs.python.org/library/os.html
Gives a complete reference if you would like to change directory or give paths.
You can for example give relative paths and access specific files.
If you would like to execute commands then http://docs.python.org/library/commands.html provides nice wrappers for the os.popen() function

Categories

Resources