Reputation: 3783
Why does the second slash does not get replaced with double slash when I do the following in Python shell?:
>>> p = 'M:\django\newenv\django_projects\mediaproject\mediaproject\media'
>>> p
'M:\\django\newenv\\django_projects\\mediaproject\\mediaproject\\media'
I think this is causing an error I am getting when trying to os.listdir(p)
:
FileNotFoundError: [WinError 3] The system cannot find the path specified: 'M:\\django\newenv\\django_projects\\mediaproject\\mediaproject\\media'
Or is there any other cause of the error? The directory exists for sure and is copy-pasted from Windows file explorer.
EDIT:
I think this is because the second slash preceded the n
character, so it gets treated as newline character. But how do I work around that (in real world I will not be typing the path manually)?
Upvotes: 1
Views: 1221
Reputation: 1850
Try
p = r'M:\django\newenv\django_projects\mediaproject\mediaproject\media'
os.listdir(p)
Adding a r
before a string prevents escape sequence interpretation inside the string. Therefore, the string is only interpreted as a raw string.
The difference between a raw string and a normal string, is how they deal with escape sequences. A raw string will always treat a \n
as two separate characters, a \
followed by a n
. On the other hand a normal string will treat the \n
as a single character.
EX.
raw_string = r"\n"
string = "\n"
print(len(raw_string))
print(len(string))
OUTPUT
2
1
Upvotes: 3
Reputation: 148910
What happens here is that '\n'
is the control character NewLine, unicode U+0010. As neither '\d'
nor '\m'
are special they are left unchanged. It may be more clear when you try to print p
:
>>> print(p)
M:\django
ewenv\django_projects\mediaproject\mediaproject\media
The \
characters that appeared as \\
are actually a single \
in the string, and \n
actually is a new line.
The 2 foolproof ways to insert \
in a string are:
consistently double them:
p = 'M:\\django\\newenv\\django_projects\\mediaproject\\mediaproject\\media'
use the r'...'
construct:
p = r'M:\django\newenv\django_projects\mediaproject\mediaproject\media'
The latter is easier when you copy/paste a path.
Beware, other \x
characters are special: \a
, \b
, \f
, \r
, \t
, \v
.
In addition, '\xab'
is the character of code ab (for example '\x41' is 'A' in the ascii charset) '\uabcd'
is the unicode character U+abcd, and '\U00abcdef'
is the unicode character U+abcdef.
Upvotes: 2
Reputation: 2891
Working on the comments, I think OP needs a way to parse the MEDIA_ROOT
env variable into an internal variable to his script.
To this goal, I suggest trying to get the environment variable using os.environ and parsing it into a python path with os.path.abspath. Example code below:
import os
import os.path
try:
media_root = os.path.abspath(os.environ['MEDIA_ROOT'])
except KeyError:
media_root = None
# Alternatively you can just raise the exception here if you want to halt
Alternatively, if your MEDIA_ROOT variable comes directly from django.conf.settings.MEDIA_ROOT you could, for your peace of mind, wrap it into an abspath, but I have a sneaky suspicion that django already does that for you.
Upvotes: 1