Почему помещение пути Windows в переменную не заменяет отдельную косую черту двойной косой чертой? - PullRequest
1 голос
/ 24 мая 2019

Почему второй слеш не заменяется двойным слешем, когда я делаю следующее в оболочке Python?:

>>> p = 'M:\django\newenv\django_projects\mediaproject\mediaproject\media'
>>> p
'M:\\django\newenv\\django_projects\\mediaproject\\mediaproject\\media'

Я думаю, что это вызывает ошибку, которую я получаю при попытке os.listdir(p):

FileNotFoundError: [WinError 3] Системе не удается найти путь Оговаривается: 'M: \\ Джанго \ newenv \\ django_projects \\ mediaproject \\ mediaproject \\ медиа'

Или есть какая-то другая причина ошибки? Каталог существует наверняка и копируется из проводника Windows.

EDIT

Я думаю, это потому, что вторая косая черта предшествовала символу n, поэтому он рассматривается как символ новой строки. Но как мне обойти это (в реальном мире я не буду вводить путь вручную)?

Ответы [ 3 ]

3 голосов
/ 24 мая 2019

Попробуйте

 p = r'M:\django\newenv\django_projects\mediaproject\mediaproject\media'

 os.listdir(p)

Добавление r перед строкой предотвращает интерпретацию escape-последовательности внутри строки.Следовательно, строка интерпретируется только как необработанная строка.

Разница между необработанной строкой и обычной строкой в ​​том, как они работают с escape-последовательностями.Необработанная строка всегда будет обрабатывать \n как два отдельных символа, \, за которыми следует n.С другой стороны, обычная строка будет обрабатывать \n как один символ.

EX.

raw_string = r"\n"
string = "\n"

print(len(raw_string)) 
print(len(string)) 

ВЫХОД

2
1
1 голос
/ 24 мая 2019

Здесь происходит то, что '\n' является управляющим символом NewLine, Unicode U + 0010. Поскольку ни '\d', ни '\m' не являются особенными, они остаются без изменений. Это может быть более ясно, когда вы пытаетесь напечатать p:

>>> print(p)
M:\django
ewenv\django_projects\mediaproject\mediaproject\media

Символы \, появившиеся как \\, на самом деле представляют собой один \ в строке, а \n фактически является новой строкой.

2 надежных способа вставить \ в строку:

  • последовательно удваивает их:

    p = 'M:\\django\\newenv\\django_projects\\mediaproject\\mediaproject\\media'
    
  • используйте конструкцию r'...':

    p = r'M:\django\newenv\django_projects\mediaproject\mediaproject\media'
    

Последнее проще при копировании / вставке пути.


Осторожно, другие \x символы являются специальными: \a, \b, \f, \r, \t, \v. Кроме того, '\xab' является символом кода ab (например, '\ x41' является 'A' в кодировке ascii) '\uabcd' является символом Unicode U + abcd, а '\U00abcdef' является символом Unicode U + abcdef .

1 голос
/ 24 мая 2019

Работая над комментариями, я думаю, что OP нужен способ для анализа переменной MEDIA_ROOT env во внутренней переменной его сценария.

Для этой цели я предлагаю попытаться получить переменную окружения с помощью os.environ и проанализировать ее в python-пути с помощью os.path.abspath. Пример кода ниже:

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

В качестве альтернативы, если ваша переменная MEDIA_ROOT поступает непосредственно из django.conf.settings.MEDIA_ROOT , вы можете, для вашего спокойствия, обернуть ее в абспат, но у меня есть хитрое подозрение, что django уже делает это для тебя.

...