2017-01-04 2 views
2

Есть ли способ получить цель символической ссылки, используя pathlib? Я знаю, что это можно сделать, используя os.readlink().Получение цели символической ссылки с pathlib

Я хочу создать словарь, составленный ссылками и их целевыми файлами.

links = [link for link in root.rglob('*') if link.is_symlink()] 
files = [Path(os.readlink(str(pointed_file))) for pointed_file in links] 

Редактировать ... и я хочу, чтобы фильтровать все пути, не absoulute

link_table = {link : pointed_file for link, pointed_file in zip(links, files) if pointed_file.is_absolute()} 

ответ

-1

Да, Path.resolve() является то, что вы хотите:

links = [p for p in root.rglob('*') if p.is_symlink()] 
files = [p.resolve() for p in links] 

Или, чтобы получить словарь, как вы говорите, вы хотите:

symlinks = {p: p.resolve() for p in root.rglob('*') if p.is_symlink()} 

Update: Если вам нужны относительные пути, используйте relative_to():

def relative_to(p : Path): 
    p_str = str(p) 
    cwd_str = str(Path.cwd()) 
    if p_str.startswith(cwd_str): 
     return p.relative_to(cwd_str) 
    return p  

link_tablev2 = { 
    link: relative_to(link.resolve()) 
    for link in root.rglob('*') 
    if link.is_symlink() 
    if relative_to(link.resolve()).is_absolute() 
} 
+0

Это почти то, что я хочу, проблема в том, что 'resolve' делает путь абсолютным, пока я не хочу поведения. Следующий шаг - отфильтровать все символические ссылки, которые не являются абсурдом –

3

Нет, это в настоящее время не представляется возможным, чтобы получить результаты от pathlib что os.readlink() дает. Path.resolve() не работает для неработающих ссылок и либо поднимает FileNotFoundError (Python < 3.5), либо возвращает потенциально странный путь (Python 3.6). По-прежнему можно получить старое поведение с Path.resolve(True), хотя это означает несовместимость между версиями (кстати, в документации по пакетам и в разделе «Портирование документа выпуска Py3.6»).

Также относительно обновленного вопроса об абсолютных путях, несмотря на принятый ответ, os.readlink() - единственный способ проверить, является ли символическая ссылка абсолютной или относительной. Path.relative_to() как имя говорит, преобразует существующий путь в относительный, не проверяя, начинается ли путь назначения символической ссылки с '/' или нет. То же самое относится к Path.is_absolute(). Наконец Path.resolve() для существующих целей, преобразует путь назначения, чтобы он уничтожал необходимую информацию на этом пути.

И странном пути выше, я имею в виду, скажем, в /home/test есть символическая .myapp указывая на .config/myapp/config. Если .config/myapp не существует, а код написан в Py < = 3.5, Path.resolve() может вызвать исключение, и приложение может сообщить пользователю о пропавшем файле. Теперь, если он вызван из Py3.6 без изменений кода, он разрешает ~/.config/myapp, исключение не выбрасывается, поэтому отметьте около .resolve() проходов, но затем, вероятно, другое исключение будет отправлено позже, когда приложение попытается открыть файл для чтения, поэтому пользователь может получить сообщение, что файл ~/config/myapp не найден, хотя на самом деле этого не хватает. Это может быть еще хуже - когда приложение будет делать Path('/home/test/.myapp').resolve().open('w') (не обязательно в один шаг, но скажем, как часть некоторого процесса санитарной обработки), то создается просто неправильный файл. Конечно, в следующий раз, когда приложение вызывается, путь разрешает один уровень глубже, до /home/test/.config/myapp/config (поскольку Path.resolve() не проверяет, является ли myapp - это каталог или нет), и чтение и запись с ошибкой NotADirectoryError (с небольшим количеством вводимых в заблуждение "Not a directory: /home/test/.config/myapp/config" как описание ...).

Смежные вопросы