Определите, допустим ли путь в конструкторе класса - PullRequest
3 голосов
/ 15 апреля 2019

Не нарушая правила, согласно которым конструктор должен работать , мне нужно определить, является ли предоставленная строка (destination_directory) допустимым путем, прежде чем назначать его в конструкторе.

Он не должен существовать, но строка предоставления должна быть допустимой, то есть не содержать недопустимых символов или недопустимых символов.Мой проект будет работать только на Windows, а не на Linux.

Я просмотрел эту страницу, но, похоже, ответы пытаются открыть каталог, чтобы проверить, верна ли предоставленная строка.

Я также попытался os.path.isabs(path), ноэто не дает результаты, которые мне нужны.Например, он говорит, что T:\\\\Pictures - это абсолютный путь, хотя это может быть правдой, \\\\ должен означать, что путь неверен.

Существует ли чистый, возможно, однострочный способ достижения того, что яхотите?

def __init__(self, destination_directory: str)
    self._validate_path(path=destination_directory)
    self.destination_directory = destination_directory

def _validate_path(self, path)
    # code to validate path should go here.

Ответы [ 2 ]

1 голос
/ 15 апреля 2019

Теперь немного о пути, он содержит как минимум букву диска и подкаталоги.

У нас также есть правила о , какие символы не разрешены в каталогах.Мы также знаем, что буква диска содержит один символ.

Вместо того, чтобы разрешать пользователям нашего класса указывать полный путь, мы разбиваем его и разрешаем только допустимые строки для имен каталогов и одну букву для диска.Когда все проверено, мы можем использовать модуль os для построения нашего пути.

Вот как я бы структурировал свой Folder класс:

class Folder:

    def __init__(self, *subdirectories, root_drive):
        self._validate_drive_letter(letter = root_drive)
        self._validate_path(path=subdirectories)

        self._root_drive = root_drive
        self._subdirectories = subdirectories

    def _validate_drive_letter(self, letter):
        if not letter or len(letter) > 2 or not letter.isalpha():
            raise ValueError("Drive letter is invalid")

    def _validate_path(self, path):
        self._forbidden_characters = ["<", ">", ":", "/", '"', "|", "?", "*", '\\']
        for character in path:
            for item in character:
                if item in self._forbidden_characters:
                    raise ValueError("Directory cannot contain invalid characters")

    def construct_full_path(self) -> str:
        # use the os module and constructor parameters to build a valid path

    def __str__(self) -> str:
        return f"Drive Letter: {self._root_drive} Subdirectories: {self._subdirectories}"

Main:

def main():

    try:

        portable_drive = Folder("Pictures", "Landscape", root_drive="R") # Valid
        # Using the construct_full_path() function, the returned string would be:
        # R:\Pictures\Landscape
        # Notice the user doesn't provide the : or the \, the class will do it.

        vacation_pictures = Folder("Vac??tion", root_drive="T") # Will raise ValueError
        # If we fix the error and call construct_full_path() we will get T:\Vacation 

    except ValueError as error:
        print(error)
    else:
        print(portable_drive)
        print(vacation_pictures)


if __name__ == "__main__":
    main()

Возможно, он не самый лучшийподход, но это работает.Я знаю, что вложенный цикл for плох, но я не вижу другого способа проверки отдельных символов string.

0 голосов
/ 15 апреля 2019

A regex решение:

import re

windows_path_regex = re.compile(r"""
\A
(?:(?:[a-z]:|\\\\[a-z0-9_.$\●-]+\\[a-z0-9_.$\●-]+)\\|  # Drive
   \\?[^\\/:*?"<>|\r\n]+\\?)                           # Relative path
(?:[^\\/:*?"<>|\r\n]+\\)*                              # Folder
[^\\/:*?"<>|\r\n]*                                     # File
\Z
""", re.VERBOSE|re.I)
d = windows_path_regex .match(r"\test\txt.txt")
print(bool(d))

Обратите внимание, что \ - допустимый путь, а / - нет.

Я использовал 8.18. Проверьте пути Windows в качестве ссылки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...