В Windows 7 с Python 2.7 как я могу определить, является ли путь символической ссылкой?
Это не работает os.path.islink()
, он говорит, что возвращает false, если false или не поддерживается, и путь, который я предоставляю, определенно является символической ссылкой, поэтому я предполагаю, что она не поддерживается в Windows? Что я могу сделать?
Os.path.islink на windows с python
Ответ 1
Коренная проблема заключается в том, что вы используете слишком старую версию Python. Если вы хотите придерживаться 2.x, вы не сможете воспользоваться новыми функциями, добавленными после начала 2010 года.
Одной из этих функций является обработка символических ссылок NTFS. Эта функциональность была добавлена в 3.2 в конце 2010 года. (Смотрите 3.2, 3.1 и 2.7 источник.)
Причина, по которой Python не обрабатывала символические ссылки NTFS, до этого времени заключалась в том, что до конца 2009 года этого не было. (IIRC, поддержка была включена в ядро 6.0, но для поддержки пользовательской лицензии требуется пакет обновления для Vista/2008, только 7/2008R2 и новее приходят с ним. Кроме того, вам нужен новый достаточно MSVCRT, чтобы иметь возможность доступа к этой пользовательской поддержке, а у Python есть явная политика не обновления до новых версий Visual Studio в рамках небольшой версии.)
Причина, по которой код не был перенесен обратно в 2.x, - это что никогда не будет 2.8, и исправления ошибок, такие как 2.7.3 (или 2.7.4) не получают новых функций, только исправления ошибок.
Об этом сообщается как issue 13143, и предполагаемое исправление заключается в изменении 2.7 документов, чтобы уточнить, что islink
всегда возвращает False
в Windows.
Итак, если вы хотите читать символические ссылки NTFS под Windows, либо обновляйтесь до Python 3.2+, либо вам нужно использовать win32api
, ctypes
и т.д., чтобы сделать это самостоятельно.
Или, как предлагает Martijn Pieters, вместо того, чтобы делать это самостоятельно, используйте стороннюю библиотеку, например jaraco.windows
, которая делает это и/или заимствовать их код.
Или, если вы действительно хотите, заимствуйте код из источника 3.2 и создайте вокруг него модуль расширения C. Если вы отсканируете от ntpath
до os
до nt
(это на самом деле posixmodule.c
), я считаю, что его кишки находятся в win32_xstat_impl
и win32_xstat_impl_w
.
Ответ 2
Это то, что я использовал, чтобы определить, является ли файл или каталог ссылкой в Windows 7:
def isLink(path):
if os.path.exists(path):
if os.path.isdir(path):
FILE_ATTRIBUTE_REPARSE_POINT = 0x0400
attributes = ctypes.windll.kernel32.GetFileAttributesW(unicode(path))
return (attributes & FILE_ATTRIBUTE_REPARSE_POINT) > 0
else:
command = ['dir', path]
try:
with open(os.devnull, 'w') as NULL_FILE:
o0 = check_output(command, stderr=NULL_FILE, shell=True)
except CalledProcessError as e:
print e.output
return False
o1 = [s.strip() for s in o0.split('\n')]
if len(o1) < 6:
return False
else:
return 'SYMLINK' in o1[5]
else:
return False
EDIT: Измененный код в соответствии с предложениями Zitrax и Annan
Ответ 3
Для каталогов:
import os, ctypes
def IsSymlink(path):
FILE_ATTRIBUTE_REPARSE_POINT = 0x0400
return os.path.isdir(path) and (ctypes.windll.kernel32.GetFileAttributesW(unicode(path)) & FILE_ATTRIBUTE_REPARSE_POINT):