Как правильно переопределить методы keys (), items (), __iter__ при переопределении dict? - PullRequest
0 голосов
/ 20 октября 2018

Я пытаюсь сделать улучшение в dict, которое поддерживает файловые операции в определенной папке так, как это делается в dict.Ниже приведен пример

if __name__ == "__main__":
    d = FolderDict("LALALA", create_new=True)
    d["File1"] = "Content of file 1"
    d["File2"] = "Content of file 2"

. Он создает два файла в папке LALALA с правильным содержимым.Я мог бы правильно обрабатывать методы get, set, contains, del, pop, но я не могу обернуть руку вокруг методов keys (), values ​​(), iter .

Я хочувсе имена файлов, которые будут напечатаны, когда я вызываю keys (), и когда я его пишу, я хочу

k - имя файла v - содержимое файла

Следуя моему коду, пожалуйста, имейтевзгляд и помощь.

import os


class FolderDict(dict):

    def get_absolute_path(self, file_name):
        return os.path.join(self.folder_path, file_name)

    def __init__(self, folder_path, create_new=False):
        super().__init__()
        self.folder_path = folder_path
        if os.path.exists(self.folder_path) and os.path.isdir(self.folder_path):
            for file_name in os.listdir(self.folder_path):
                with open(self.get_absolute_path(file_name), "r") as reader:
                    self[file_name] = reader.read()
        else:
            if create_new:
                os.makedirs(folder_path, exist_ok=True)
            else:
                raise FileNotFoundError("[Errno 2] No such file or directory: '{}'".format(self.folder_path))

    def __getitem__(self, item):
        with open(self.get_absolute_path(item), "r") as reader:
            return reader.read()

    def __setitem__(self, key, value):
        """
        Be careful,it will overwrite the existing file.
        We support w mode not a mode now
        """
        with open(self.get_absolute_path(key), "w") as writer:
            writer.write(value)

    def keys(self):
        yield from super().keys()

    def __iter__(self):
        yield from self.keys()

    def __contains__(self, item):
        return os.path.exists(self.get_absolute_path(item))

    def __missing__(self, key):
        raise FileNotFoundError("[Errno 2] No such file or directory: '{}'".format(self.get_absolute_path(key)))

    def __delitem__(self, key):
        os.remove(self.get_absolute_path(key))

    def get(self, k, default=None):
        return self[k] if k in self else default

    def pop(self, k):
        content = self[k]
        os.remove(self.get_absolute_path(k))
        return content

    def __repr__(self):
        return "FolderDict for folder {}".format(self.folder_path)

    __str__ = __repr__


if __name__ == "__main__":
    d = FolderDict("LALALA", create_new=True)
    d["File1"] = "Content of file 1"
    d["File2"] = "Content of file 2"
    d["File3"] = "Content of file 3"

    for k,v in d:
        print(k)

1 Ответ

0 голосов
/ 20 октября 2018

1: вы даже не сохранили информацию об именах файлов, поэтому ваша функция keys () не работает

2: наследовать класс UserDict вместо того, чтобы наследовать класс dict

3:Я не могу понять, что означает наследовать класс, например dict / UserDict ....

4: Чтобы использовать FolderDict как настоящий dict, вам нужно написать __iter__ __next__ __getitem__ __setitem__ __next__ __getattribute__ __delitem__ keys items values ......в вашем классе.

import os
from collections import UserDict


class FolderDict(UserDict):

    def get_absolute_path(self, file_name):
        return os.path.join(self.folder_path, file_name)

    def __init__(self, folder_path, create_new=False):
        super().__init__()
        self._dict = {}
        self.folder_path = folder_path
        if os.path.exists(self.folder_path) and os.path.isdir(self.folder_path):
            for file_name in os.listdir(self.folder_path):
                with open(self.get_absolute_path(file_name), "r") as reader:
                    self[file_name] = reader.read()
        else:
            if create_new:
                os.makedirs(folder_path, exist_ok=True)
            else:
                raise FileNotFoundError("[Errno 2] No such file or directory: '{}'".format(self.folder_path))

    def __getitem__(self, item):
        with open(self.get_absolute_path(item), "r") as reader:
            return reader.read()

    def __setitem__(self, key, value):
        """
        Be careful,it will overwrite the existing file.
        We support w mode not a mode now
        """
        with open(self.get_absolute_path(key), "w") as writer:
            writer.write(value)
        self._dict[key] = value

    def keys(self):
        return self._dict.keys()

    def __iter__(self):
        return iter(self._dict.items())

    def __contains__(self, item):
        return os.path.exists(self.get_absolute_path(item))

    def __missing__(self, key):
        raise FileNotFoundError("[Errno 2] No such file or directory: '{}'".format(self.get_absolute_path(key)))

    def __delitem__(self, key):
        os.remove(self.get_absolute_path(key))

    def get(self, k, default=None):
        return self[k] if k in self else default

    def pop(self, k):
        content = self[k]
        os.remove(self.get_absolute_path(k))
        return content

    def __repr__(self):
        return "FolderDict for folder {}".format(self.folder_path)

    __str__ = __repr__


if __name__ == "__main__":
    d = FolderDict("LALALA", create_new=True)
    d["File1"] = "Content of file 1"
    d["File2"] = "Content of file 2"
    d["File3"] = "Content of file 3"

    for k,v in d:
        print(k,v)
    for k in d.keys():
        print(k)
...