Подтвердить что ты не робот

Os.path.islink на windows с python

В Windows 7 с Python 2.7 как я могу определить, является ли путь символической ссылкой? Это не работает os.path.islink(), он говорит, что возвращает false, если false или не поддерживается, и путь, который я предоставляю, определенно является символической ссылкой, поэтому я предполагаю, что она не поддерживается в Windows? Что я могу сделать?

4b9b3361

Ответ 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):

Источник