【问题标题】:Weird KeyError || Python3.6.1奇怪的键错误 || Python3.6.1
【发布时间】:2017-12-03 14:58:19
【问题描述】:

我正在尝试在 python 中制作类似 FileSystem 的东西。我的目标是制作可以包含一些数据的文件和可以包含一些文件的目录。然后我有一些简单的命令

  • cd

  • ls

  • mk_dir

  • mk_file

所以,现在我有一个问题: 有与 Directory 不同的 DirectoryBase 类,因为它没有 ParentDir(其中的目录是文件/目录保存的)。然后是目录类,它扩展了 DirectoryBase 并覆盖了 path() 方法(方法返回文件/目录的路径),并且数据字典有另一个默认键:'..',但是当我试图在数据字典中找到它时,它会引发 KeyError。另一个奇怪的事情是,我正在测试文件/目录是否存在,如果不存在,它将返回,所以我不知道这是怎么可能的,它得到了 KeyError。

这是我的代码:

class AttributeDictionary(dict):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.__getattr__ = self.__getitem__
        self.__setattr__ = self.__setitem__
        self.__delattr__ = self.__delitem__


class FileManager(object):
    def __init__(self):
        self.disk_dir = DirectoryBase('__disk__')
        self.current_dir = self.disk_dir

    def _find(self, path):
        """ Gets file/dir object using path """
        _cd = self.current_dir
        for part in path:
            _cd = _cd[part]
        return _cd

    def cmd_cd(self, path):
        """ Classic unix `cd` command """
        f = self._find(path)
        if f is DirectoryBase:
            self.current_dir = f
        else:
            return FileSystemError('DirectoryNotFound')

    def cmd_ls(self):
        """ Classic unix `ls` command """
        return ConsoleOutput(''.join([f'{i}\n' for i in self.current_dir.data]))

    def cmd_mkfile(self, name):
        """ file making command """
        self.current_dir.__setitem__(name, File(name, self.current_dir))

    def cmd_mkdir(self, name):
        """ file making command """
        self.current_dir.__setitem__(name, Directory(name, self.current_dir))


class File(object):
    def __init__(self, name, pd):
        self.data = [0x00]
        self.name = name
        self.pd = pd

    def path(self):
        return [self.name] + self.pd.path()

    def __sizeof__(self):
        return len(self.data)


class DirectoryBase(AttributeDictionary):
    def __init__(self, name, **kwargs):
        super().__init__(**kwargs)
        self.name = name
        self.data = {'.': self}

    def path(self):
        return self.name

    def __getitem__(self, item):
        if item in self.data.keys():
            return FileSystemError('FileNotFound')
        return self.data[item] # KeyError: '..' found here

    def __setitem__(self, key, value):
        if key in self.data.keys():
            return FileSystemError('FileAlreadyExists')
        self.data[key] = value

    def __delitem__(self, key):
        if key in self.data.keys():
            return FileSystemError('FileNotFound')
        self.data.__delitem__(key)


class Directory(DirectoryBase):
    def __init__(self, name, pd, **kwargs):
        super().__init__(name, **kwargs)
        self.pd = pd
        self.data = {'.': self, '..': self.pd}

    def path(self):
        return [self.name] + self.pd.path()


if __name__ == '__main__':
    fs = FileManager()
    fs.cmd_mkdir('test')
    print(fs.cmd_ls())
    fs.cmd_cd(['test'])
    fs.cmd_mkfile('idk.txt')
    print(fs.cmd_ls())
    fs.cmd_cd(['..'])
    print(fs.cmd_ls())

错误如下所示:

.
test
Traceback (most recent call last):

.
  File "/Users/jan/PycharmProjects/Xaon/src/fs.py", line 106, in <module>
test
    fs.cmd_cd(['..'])
idk.txt

  File "/Users/jan/PycharmProjects/Xaon/src/fs.py", line 32, in cmd_cd
    f = self._find(path)
  File "/Users/jan/PycharmProjects/Xaon/src/fs.py", line 27, in _find
    _cd = _cd[part]
  File "/Users/jan/PycharmProjects/Xaon/src/fs.py", line 76, in __getitem__
    return self.data[item]
KeyError: '..'

或者当我删除打印时:

Traceback (most recent call last):
  File "/Users/jan/PycharmProjects/Xaon/src/fs.py", line 106, in <module>
    fs.cmd_cd(['..'])
  File "/Users/jan/PycharmProjects/Xaon/src/fs.py", line 32, in cmd_cd
    f = self._find(path)
  File "/Users/jan/PycharmProjects/Xaon/src/fs.py", line 27, in _find
    _cd = _cd[part]
  File "/Users/jan/PycharmProjects/Xaon/src/fs.py", line 76, in __getitem__
    return self.data[item]
KeyError: '..'

对不起,如果太混乱了,我是初学者,我的英语也很糟糕。

【问题讨论】:

  • 你应该在学习的时候切换到 Python 3.x。
  • 我使用的是python 3.6.1
  • 抱歉,假设您定义了一个继承自 object - class File(object: 的类
  • Catch the error 并在 except 套件中检查您的数据。也许打印self.dataitem

标签: python dictionary keyerror


【解决方案1】:

代码逻辑有缺陷:

def __getitem__(self, item):
    if item in self.data.keys():
        return FileSystemError('FileNotFound')
    return self.data[item] # KeyError: '..' found here

当键存在时你会抛出一个错误。只需否定条件(并删除.keys(),这在 Python 2 中是无用且无用的,甚至是性能杀手):

def __getitem__(self, item):
    if item not in self.data:
        return FileSystemError('FileNotFound')
    return self.data[item]

__delitem__ BTW 也有同样的错误。

修复后(并使用str 对大多数不存在/未显示的类进行存根)我得到以下输出:

.
test

.
idk.txt
test

.
idk.txt
test

【讨论】:

  • 谢谢,但它并没有解决我的问题......但现在我看到问题出在 cd 命令中,因为它找不到测试目录
  • 虽然没有抛出 KeyError,但不是 Traceback 中指向的行。
  • 您当时没有完全阅读:删除.keys(),但主要是在您的条件中添加notsetitem 的条件可以,因为您想避免覆盖现有的,但 get & del 需要否定。
  • 我测试了你的代码,现在没有任何异常
猜你喜欢
  • 2013-01-12
  • 2017-12-20
  • 1970-01-01
  • 1970-01-01
  • 2010-11-17
  • 1970-01-01
  • 1970-01-01
  • 2014-10-11
  • 2012-04-27
相关资源
最近更新 更多