I am writing a python script 2.5 in Windows whose CurrentDir = C:\users\spring\projects\sw\demo\753\ver1.1\011\rev120\source my file is test.py. From this path I would like to access files in this path: C:\users\spring\projects\sw\demo\753\ver1.1\011\rev120\Common\
I tried using os.path.join but it does not work and I from the docs I understand why.
So what could be the best pythonic solution for this?
currentdir = os.getcwd()
config_file_path = os.path.join(currentdir,"\\..\\Common")
Your problem can be solved by using os.path.join, but you're not using it properly.
currentdir = os.getcwd()
config_file_path = os.path.join(currentdir,"\\..\\Common")
"\\..\\Common" is not a relative path, as it starts with \.
You need to join with ..\\Common, which is a relative path.
Please note that os.path.join is not a simple string concatenation function, you don't need to insert the in-between antislashes.
So fixed code would be :
config_file_path = os.path.join(currentdir,"..\\Common")
or, alternatively :
config_file_path = os.path.join(currentdir, "..", "Common")
from os.path import dirname, join
join(dirname(dirname(__file__)), 'Common')
should work.
Try this:
joined = os.path.join('C:\\users\\spring\\projects\\sw\\demo\\753\\ver1.1\\011\\rev120\\source', '..\\Common\\')
# 'C:\\users\\spring\\projects\\sw\\demo\\753\\ver1.1\\011\\rev120\\source\\..\\Common\\'
canonical = os.path.realpath(joined)
# 'C:\\users\\spring\\projects\\sw\\demo\\753\\ver1.1\\011\\rev120\\Common'
Related
I have a python code with these two line to parse a specific set of files to my function
Allfile = glob.glob(project1)
project1 ='./DDfiles/*.txt'
instead I want to add /*.txt to Allfile line and project1 should just be root path. How do i insert that Thank you!
How about this one?
all_file = [filename + ".txt" for filename in glob.glob(project1)]
It sounds to me you simply want to do this?
project1 = './DDfiles/'
all_files = glob.glob(project1 + '*.txt')
An object-oriented approach using pathlib library allows you to use with_suffix() method and in addition, the path is now not a string but a Path object which makes it much easier to reference parts of the path:
from pathlib import Path
filenames = [<a list of filenames>]
z = [Path(i).with_suffix('.txt') for i in filenames]
Or if you know your original project directory then you can also use recursive glob method of pathlib to recursively find all required files:
f = 'my_folder'
z = [i.with_suffix('.txt') for i in list(Path(f).rglob('*'))]
I'm trying to open a file like this:
with open(str(script_path) + '\\description.xml', 'w+') as file:
where script_path is equal to this:
script_path = os.path.dirname(os.path.realpath(__file__)) + '\\.tmp')
When I run this I get an error that there is no such file or directory because when it tries to open the file it sees the whole path as a string, including the escape strings. Is there any way around this?
Obviously .replace() won't work here as it won't replace the escape string. Hoping there is a clever way to do this within the os module?
Not really sure why you're adding two backslashes. You can simply create the path using a single forward slash (Linux based) or backslash (win). Something like this:
script_path = os.path.dirname(os.path.realpath(__file__)) + '/tmp/description.xml'
However, better way to achieve this would be to use os.path.join as suggested by nomansland008.
>>> import os
>>> parent_dir = "xyz"
>>> dir = "foo"
>>> file_name = "bar.txt"
>>> os.path.join(parent_dir, dir, file_name)
'xyz/foo/bar.txt'
You won't have to bother about whether the string has slash(or not). It will be taken care by join.
In your case it can simply be:
os.path.join(os.path.dirname(os.path.realpath(__file__)), 'tmp', 'description.xml')
Should work, provided the files and directories exist.
I have this below Python script that fetches a file from one location and copies that to another Target location. The below code works just fine if I define the paths with the absolute locations.
I am trying to rather define this using variables, which when done does not execute the script. There is no error that is thrown but the code does not seem to be executed.
Code:
Path_from = r'/Users/user/Desktop/report'
Path_to = r'/Users/user/Desktop/report'
for root, dirs, files in os.walk((os.path.normpath(Path_from)), topdown=False):
for name in files:
if name.endswith('{}.txt'.format(date)):
print
"Found"
SourceFolder = os.path.join(root, name)
shutil.copy2(SourceFolder, Path_to)
I want to change the code from
Path_from = r'/Users/user/Desktop/report'
to
base_path = /Users/user/Desktop/
Path_from = r'base_path/{}'.format(type)
I would recommend you leave all the current working directory concerns to the user - if they want to specify a relative path, they can enter into the directory to which it relates before invoking the python and providing relative paths.
This is what just about every linux tool and program does - rarely do they take a 'base path', but rather leave the job of providing valid paths relative to the current directory ( or absolute ) to the user.
If you're dedicated to the idea of taking another parameter as the relative path, it should be pretty straightforward to do. Your example doesn't have valid python syntax, but it's close:
$ cat t.py
from os.path import join
basepath="/tmp"
pathA = "fileA"
pathB = "fileB"
print(join(basepath,pathA))
print(join(basepath,pathB))
note however that this prevents an absolute path being provided at script execution time.
You could use a format instead,
basepath="/tmp"
pathA = "fileA"
pathB = "fileB"
print( "{}/{}".format(basepath, pathA) )
print( "{}/{}".format(basepath, pathB) )
But then you're assuming that you know how to join paths on the operating system in question, which is why os.path.join exists.
If I'm reading this right, you could use pathlib, specifically pathlib.Path code would look like
from pathlib import Path
import re
import shutil
path_from = Path("/") / "Users" / "user" / "Desktop" # Better IMO
# path_from = Path("/Users/user/Desktop")
path_to = Path("/") / "Users" / "user" / "OtherDesktop"
datename = "whatever"
for x in path_from.glob("*.txt"):
if re.search(r"{}$".format(datename), x.stem): # stem is whatever is before the extension
# ex. something.txt -> something
shutil.copy(str(path_from / x.name), str(path_to / x.name))
Say I want to delete 'Core.dll' after 'git pull', so I write a hook.
import os
dir = os.path.dirname(__file__)
try:
os.remove(os.path.abspath(dir+os.sep+".."+os.sep+".."+os.sep+"Assets"+os.sep+"Plugins"+os.sep+"Core.dll"))
except OSError:
pass
Say the hook path is 'E:\client\.git\hooks', the file I want to delete is in 'E:\client\Assets\Plugins\Core.dll'.
I think my way is very silly, is there any elegant way to get the relative path?
Using pathlib:
from pathlib import Path
(Path(__file__).absolute().parent.parent.parent/'Assets'/'Plugins'/'Core.dll').unlink()
Antti's solution is the best in Python 3. For Python 2, you could use os.pardir and os.path.join:
os.path.abspath(os.path.join(d, os.pardir, os.pardir, "Assets", "Plugins", "Core.dll"))
os.path.relpath would be what you asked for. You should also be using os.path.join instead of that long list of + and sep. In Python 3's pathlib, there's relative_to. It appears your code is trying to apply a relative path, not get it in relative form. In that case, joinpath and normpath or realpath might help.
More readable solution:
import os
from contextlib import suppress
with suppress(OSError):
dir = os.path.dirname(__file__)
while '.git' in dir:
dir = os.path.dirname(dir)
os.remove(
os.path.join(
dir,
'Assets',
'Plugins',
'Core.dll'
)
)
I have written a code in python which uses / to make a particular file in a folder, if I want to use the code in windows it will not work, is there a way by which I can use the code in Windows and Linux.
In python I am using this code:
pathfile=os.path.dirname(templateFile)
rootTree.write(''+pathfile+'/output/log.txt')
When I will use my code in suppose windows machine my code will not work.
How do I use "/" (directory separator) in both Linux and Windows?
Use os.path.join().
Example: os.path.join(pathfile,"output","log.txt").
In your code that would be: rootTree.write(os.path.join(pathfile,"output","log.txt"))
Use:
import os
print os.sep
to see how separator looks on a current OS.
In your code you can use:
import os
path = os.path.join('folder_name', 'file_name')
You can use os.sep:
>>> import os
>>> os.sep
'/'
os.path.normpath(pathname) should also be mentioned as it converts / path separators into \ separators on Windows. It also collapses redundant uplevel references... i.e., A/B and A/foo/../B and A/./B all become A/B. And if you are Windows, these all become A\B.
If you are fortunate enough to be running Python 3.4+, you can use pathlib:
from pathlib import Path
path = Path(dir, subdir, filename) # returns a path of the system's path flavour
or, equivalently,
path = Path(dir) / subdir / filename
Some useful links that will help you:
os.sep
os.path
os.pathsep
Do a import os and then use os.sep
You can use "os.sep "
import os
pathfile=os.path.dirname(templateFile)
directory = str(pathfile)+os.sep+'output'+os.sep+'log.txt'
rootTree.write(directory)
Don't build directory and file names your self, use python's included libraries.
In this case the relevant one is os.path. Especially join which creates a new pathname from a directory and a file name or directory and split that gets the filename from a full path.
Your example would be
pathfile=os.path.dirname(templateFile)
p = os.path.join(pathfile, 'output')
p = os.path.join( p, 'log.txt')
rootTree.write(p)
If someone is looking for something like this:
He/she wants to know the parent directory and then go to the sub-folders and maybe than to a specific file. If so, I use the following approach.
I am using python 3.9 as of now. So in that version, we have the os module for handling such tasks. So, for getting the parent directory:
parent_dir = os.path.pardir
It's a good coding practice to not hardcode the file path separators (/ or \). Instead, use the operating system dependant mechanism provided by the above-mentioned os module. It makes your code very much reusable for other purposes/people. It goes like this (just an example) :
path = os.path.pardir + os.sep + 'utils' + os.sep + 'properties.ini'
print(f'The path to my global properties file is :: {path}')
Output:
..\utils\properties.ini
You can surely look at the whole documentation here : https://docs.python.org/3/library/os.html
I use pathlib for most things, so I like: pathlib.os.sep.
Usually pathlib is the better choice if you don't need os!