pathlib is an OO library, not a communication protocol. Just send strings.
Windows can handle paths with forward slashes just fine, and both pathlib and os.path can normalise such paths for you. You probably want to normalise paths in your protocol to use POSIX path separators (forward slashes).
You can convert relative Windows paths to POSIX paths using pathlib.PurePosixPath(), for example:
>>> from pathlib import Path, PurePosixPath
>>> Path('relative\path\on\windows')
WindowsPath('relative\path\on\windows')
>>> PurePosixPath(_)
PurePosixPath('relative/path/on/windows')
>>> str(_)
'relative/path/on/windows'
If your server receives a relative paths using Windows conventions, use PureWindowsPath() to convert it to a pathlib object, then pass that to Path() to convert:
>>> from pathlib import Path, PureWindowsPath
>>> received = 'relative\path\on\windows'
>>> PureWindowsPath(received)
PureWindowsPath('relative/path/on/windows')
>>> Path(_)
PosixPath('relative/path/on/windows')
If you keep paths as strings, then you can use str.replace(os.altsep, os.sep) to achieve the same on the Windows side before sending:
>>> import os
>>> p = 'relative\path\on\windows'
>>> p.replace(os.altsep, os.sep)
'relative/path/on/windows'
and you can always just use relative_path.replace('\\', os.sep) to force the issue.
pathlib is an OO library, not a communication protocol. Just send strings.
Windows can handle paths with forward slashes just fine, and both pathlib and os.path can normalise such paths for you. You probably want to normalise paths in your protocol to use POSIX path separators (forward slashes).
You can convert relative Windows paths to POSIX paths using pathlib.PurePosixPath(), for example:
>>> from pathlib import Path, PurePosixPath
>>> Path('relative\path\on\windows')
WindowsPath('relative\path\on\windows')
>>> PurePosixPath(_)
PurePosixPath('relative/path/on/windows')
>>> str(_)
'relative/path/on/windows'
If your server receives a relative paths using Windows conventions, use PureWindowsPath() to convert it to a pathlib object, then pass that to Path() to convert:
>>> from pathlib import Path, PureWindowsPath
>>> received = 'relative\path\on\windows'
>>> PureWindowsPath(received)
PureWindowsPath('relative/path/on/windows')
>>> Path(_)
PosixPath('relative/path/on/windows')
If you keep paths as strings, then you can use str.replace(os.altsep, os.sep) to achieve the same on the Windows side before sending:
>>> import os
>>> p = 'relative\path\on\windows'
>>> p.replace(os.altsep, os.sep)
'relative/path/on/windows'
and you can always just use relative_path.replace('\\', os.sep) to force the issue.
.as_posix() is way forward.
from pathlib import Path
p = Path('./my_dir/my_file.txt')
print(p)
# my_dir\my_file.txt
print(p.as_posix())
# my_dir/my_file.txt
Windows path to Python path
python - How to resolve a server path on Windows with Pathlib? - Stack Overflow
python - Convert WindowsPath to String - Stack Overflow
pathlib.Path.absolute() mishandles drive-relative Windows paths
Videos
I have been searching the web for a solution without a result.
I made this small script that can be used. Feel free to use it.
I wonder is there a better solution on the issue to convert windows path to python path?
"""
A path, in Windows "C:\Folder" . in Python it is "C:/Folder".
In Python the "\" character can get interpreted as the ESCAPE character.
When an 'r' or 'R' prefix is present, a character following a backslash is
included in the string without change, and all backslashes are left in the string.
"""
def main():
# - YOUR INPUT - IMPORTANT: keep the r in front of path string here.
win_path = r"<TYPE YOUR PATH HERE>"
# Call function to convert from windows to Python path.
path_py = py_path(win_path)
print("Your Python Path: ", path_py)
def py_path(win_path):
python_path = "" # The result of this script.
# Convert to ASCII list
ascii_values_list = []
for character in win_path:
ascii_values_list.append(ord(character))
# Replace all ASCII values for "\" (=92) with value for "/" (=47).
for i in range(0, len(ascii_values_list)):
if ascii_values_list[i] == 92:
ascii_values_list[i] = 47
path_py = "" # Convert ASCII list to string
for val in ascii_values_list:
path_py = path_py + chr(val)
if path_py[-1] != "/": # Add "/" at end of path if needed.
path_py = path_py + "/"
return path_py
if __name__ == "__main__":
main() # Script goes there.
# EOF
As most other Python classes do, the WindowsPath class, from pathlib, implements a non-defaulted "dunder string" method (__str__). It turns out that the string representation returned by that method for that class is exactly the string representing the filesystem path you are looking for. Here an example:
from pathlib import Path
p = Path('E:\\x\\y\\z')
>>> WindowsPath('E:/x/y/z')
p.__str__()
>>> 'E:\\x\\y\\z'
str(p)
>>> 'E:\\x\\y\\z'
The str builtin function actually calls the "dunder string" method under the hood, so the results are exaclty the same. By the way, as you can easily guess calling directly the "dunder string" method avoids a level of indirection by resulting in faster execution time.
Here the results of the tests I've done on my laptop:
from timeit import timeit
timeit(lambda:str(p),number=10000000)
>>> 2.3293891000000713
timeit(lambda:p.__str__(),number=10000000)
>>> 1.3876856000000544
Even if calling the __str__ method may appear a bit uglier in the source code, as you saw above, it leads to faster runtimes.
You are right, you need a string when you call glob.glob. In the last line of your code, parent_dir is a pathlib.Path object, which you cannot concatenate with the string '/*fits'. You need to explicitly convert parent_dir to a string by passing it to the built-in str function.
The last line of your code should thus read:
fspec = glob.glob(str(parent_dir)+'/*fits')
To illustrate further, consider this example:
>>> from pathlib import Path
>>> path = Path('C:\\')
>>> path
WindowsPath('C:/')
>>> str(path)
'C:\\'
>>>