The double backslash is not wrong, python represents it way that to the user. In each double backslash \\, the first one escapes the second to imply an actual backslash. If a = r'raw s\tring' and b = 'raw s\\tring' (no 'r' and explicit double slash) then they are both represented as 'raw s\\tring'.
>>> a = r'raw s\tring'
>>> b = 'raw s\\tring'
>>> a
'raw s\\tring'
>>> b
'raw s\\tring'
For clarification, when you print the string, you'd see it as it would get used, like in a path - with just one backslash:
>>> print(a)
raw s\tring
>>> print(b)
raw s\tring
And in this printed string case, the \t doesn't imply a tab, it's a backslash \ followed by the letter 't'.
Otherwise, a string with no 'r' prefix and a single backslash would escape the character after it, making it evaluate the 't' following it == tab:
>>> t = 'not raw s\tring' # here '\t' = tab
>>> t
'not raw s\tring'
>>> print(t) # will print a tab (and no letter 't' in 's\tring')
not raw s ring
So in the PDF path+name:
>>> item = 'xyz'
>>> PDF = r'C:\Users\user\Desktop\File_%s.pdf' % item
>>> PDF # the representation of the string, also in error messages
'C:\\Users\\user\\Desktop\\File_xyz.pdf'
>>> print(PDF) # "as used"
C:\Users\user\Desktop\File_xyz.pdf
More info about escape sequences in the table here. Also see __str__ vs __repr__.
The double backslash is not wrong, python represents it way that to the user. In each double backslash \\, the first one escapes the second to imply an actual backslash. If a = r'raw s\tring' and b = 'raw s\\tring' (no 'r' and explicit double slash) then they are both represented as 'raw s\\tring'.
>>> a = r'raw s\tring'
>>> b = 'raw s\\tring'
>>> a
'raw s\\tring'
>>> b
'raw s\\tring'
For clarification, when you print the string, you'd see it as it would get used, like in a path - with just one backslash:
>>> print(a)
raw s\tring
>>> print(b)
raw s\tring
And in this printed string case, the \t doesn't imply a tab, it's a backslash \ followed by the letter 't'.
Otherwise, a string with no 'r' prefix and a single backslash would escape the character after it, making it evaluate the 't' following it == tab:
>>> t = 'not raw s\tring' # here '\t' = tab
>>> t
'not raw s\tring'
>>> print(t) # will print a tab (and no letter 't' in 's\tring')
not raw s ring
So in the PDF path+name:
>>> item = 'xyz'
>>> PDF = r'C:\Users\user\Desktop\File_%s.pdf' % item
>>> PDF # the representation of the string, also in error messages
'C:\\Users\\user\\Desktop\\File_xyz.pdf'
>>> print(PDF) # "as used"
C:\Users\user\Desktop\File_xyz.pdf
More info about escape sequences in the table here. Also see __str__ vs __repr__.
Double backslashes are due to r, raw string:
r'C:\Users\user\Desktop\File_%s.pdf' ,
It is used because the \ might escape some of the characters.
>>> strs = "c:\desktop\notebook"
>>> print strs #here print thinks that \n in \notebook is the newline char
c:\desktop
otebook
>>> strs = r"c:\desktop\notebook" #using r'' escapes the \
>>> print strs
c:\desktop\notebook
>>> print repr(strs) #actual content of strs
'c:\\desktop\\notebook'
I'm concatenating a filepath to open an image with plt.imshow() as follows:
from pathlib import Path
import numpy as np
import pandas as pd
from scipy.io import loadmat
import pprint
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import os
folder = Path('D:\ ... \emotic')
#Note that \ ... \ stands for my filepath
original_database = Path(annotations_dict['train']['original_database'][0][50][0][0][0][0])
filename = Path(annotations_dict['train']['filename'][0][50][0])
image_path = os.path.join(folder, original_database, 'images', filename)
img = mpimg.imread(image_path)
imgplot = plt.imshow(img)
plt.show()
print(image_path)
print(repr(image_path))But I consistently get the following error message: UnidentifiedImageError*: cannot identify image file 'D:\\ ... \\ ... \\ ... \\ ... \\ ... \\emotic\\framesdb\\images\\frame_aztc78d4kjclxv9e.jpg'*
So obviously it can't read the filepath because all the backslashes are doubled. I've found many posts online explaining why this happens (\ is an escape character), but none explaining how to solve this. How do I enforce that the filepath passed on to the plt.imshow() function contains only single backslashes? I've tried solving this issue using the following methods:
-
os.path.normpath( ... ) ==> does nothing;
-
image_path.replace('\\', '\') ==> also does nothing;
-
using r'...' to enforce a raw string with single backslashes ==> still does nothing.
Note also that print(image_path) gives the filepath with single backslashes, while print(repr(image_path)) gives the filepath with double backslashes. And I kinda get the difference and why this is (kinda). But I don't know how to pass on the one with the single backslashes to plt.imshow(), and every method I try ends up giving me the same "double slash" error.
Any help would be greatly appreciated :D
EDIT 1 : The filepath named in the error message is correct. If I take that filepath and replace all the double slashes by single slashes, then put this into my file explorer, the correct image comes up.
EDIT 2 [SOLVED] : Turns out the error wasn't due to single vs. double backslashes in the filepath, but rather to a problem with the matplotlib.image.imread() function that for some reason can't access my image database and triggers the error. If I use an image reader from the PIL library instead, everything works fine:
Solved using this:
from PIL import Image plt.imshow(Image.open(image_path))
instead of this:
plt.imshow(mpimg.imread(image_path))
Thanks to everyone for helping me isolate the issue!
I made an automated filemanager with Python. The original target was for Linux. Today, when I tried to use in Windows the path become like this, "C:/Users/reddit_lonely/Dropbox/reddit_lonely/reddit_lonely-pending-note-test\\test\\folder".
I have been looking through solutions over the internet.
-
https://pythonconquerstheuniverse.wordpress.com/2008/06/04/gotcha-%E2%80%94-backslashes-in-windows-filenames/.
-
http://stackoverflow.com/questions/11924706/how-to-get-rid-of-double-backslash-in-python-windows-file-path-string
But nothing solve my problem. I see that the main culprit is when path.join() just directly concatenate both path with \ and / together without checking the legality of path.
I think I could make this work by delving around my codes for couple of days. And code path checking manually based on operating system. However, I would like to know if there are more straightforward ways that I could have missed.
SOLVED! The problem was because long file name. Although after I cross checked back in my Linux machine everything works fine.
No need to use str.replace or string.replace here, just convert that string to a raw string:
>>> strs = r"C:\Users\Josh\Desktop\20130216"
^
|
notice the 'r'
Below is the repr version of the above string, that's why you're seeing \\ here.
But, in fact the actual string contains just '\' not \\.
>>> strs
'C:\\Users\\Josh\\Desktop\\20130216'
>>> s = r"f\o"
>>> s #repr representation
'f\\o'
>>> len(s) #length is 3, as there's only one `'\'`
3
But when you're going to print this string you'll not get '\\' in the output.
>>> print strs
C:\Users\Josh\Desktop\20130216
If you want the string to show '\\' during print then use str.replace:
>>> new_strs = strs.replace('\\','\\\\')
>>> print new_strs
C:\\Users\\Josh\\Desktop\\20130216
repr version will now show \\\\:
>>> new_strs
'C:\\\\Users\\\\Josh\\\\Desktop\\\\20130216'
Let me make it simple and clear. Lets use the re module in python to escape the special characters.
Python script :
import re
s = "C:\Users\Josh\Desktop"
print s
print re.escape(s)
Output :
C:\Users\Josh\Desktop
C:\\Users\\Josh\\Desktop
Explanation :
Now observe that re.escape function on escaping the special chars in the given string we able to add an other backslash before each backslash, and finally the output results in a double backslash, the desired output.
Hope this helps you.
If you are using a raw-string, then you do not escape backslashes:
f(r'E:\dir')
Of course, this problem (and many others like it) can be solved by simply using forwardslashes in paths:
f('E:/dir')
Changing '\\' for '/' worked for me. I created a directory named 'a' in C:/ for this example.
>>> (Python interpreter)
>>> import os
>>> os.path.isdir('C:/a/)')
>>> True
>>> os.path.isfile('C:/a/)')
>>> False
The simple answer is
setopt extended_glob
f=/opt//bin//executable
f=${f//\/\/##//}
print -rl -- $f
This uses the ${VARIABLE//PATTERN/REPLACEMENT} form of parameter expansion. The pattern is //##, using the ## glob operator which means โone or more of the preceding character or groupโ. This glob operator requires the extended_glob option. Because the pattern is delimited by slashes, you need to protect the slashes in the pattern with a backslash, which makes the result awkward.
There is a corner case: on some systems, a path with exactly two leading slashes has a special meaning. The following code handles this special case.
setopt extended_glob
f=//special//bin//executable
case $f in
//|//[^/]*) f=//${${f#//}//\/\/##//};;
*) f=${f//\/\/##//};;
esac
print -rl -- $f
You may also want to remove a trailing slash (taking care not to break the edge case of the root directory):
if [[ $f = *[^/]*/ ]]; then f=${f%/}; fi
If you also want to simplify ./ and foo/.. segments, the a modifier does this, and also constructs an absolute path.
print -r -- $f:a
Using POSIX tr:
$ echo /opt//bin//executable | tr -s /
/opt/bin/executable
GNU tr has a long-form option that does the same thing: tr --squeeze-repeats.
why not use string.replace()?
>>> s = 'some \\\\ doubles'
>>> print s
some \\ doubles
>>> print s.replace('\\\\', '\\')
some \ doubles
Or with "raw" strings:
>>> s = r'some \\ doubles'
>>> print s
some \\ doubles
>>> print s.replace('\\\\', '\\')
some \ doubles
Since the escape character is complicated, you still need to escape it so it does not escape the '
Just use .replace() twice!
I had the following path: C:\\Users\\XXXXX\\Desktop\\PMI APP GIT\\pmi-app\\niton x5 test data
To convert \ to single backslashes, i just did the following:
path_to_file = path_to_file.replace('\\','*')
path_to_file = path_to_file.replace('**', '\\')
first operation creates ** for every \ and second operation escapes the first slash, replacing ** with a single \.
Result:
C:**Users**z0044wmy**Desktop**PMI APP GIT**pmi-app**GENERATED_REPORTS
C:\Users\z0044wmy\Desktop\PMI APP GIT\pmi-app\GENERATED_REPORTS