在ipython控制台中处理用户定义的类时出错

时间:2018-05-25 12:44:26

标签: python ipython

首先我应该说我使用的是Python 3.5.2。 当我定义自己的类时,我认为 ipython 出了问题。 因此,当我在标准python控制台中运行以下代码时,我没有收到任何错误:

class A(dict):
    def __getattribute__(self, item):
        return self[item]
a = A({'x' : 1})
a['x']

但是当我在 ipython 控制台中运行上面的代码时,我收到以下错误:

KeyError                                  Traceback (most recent call last)
/usr/local/lib/python3.5/dist-packages/IPython/core/prefilter.py in prefilter_lines(self, lines, continue_prompt)
    333                              for lnum, line in enumerate(llines) ])
    334         else:
--> 335             out = self.prefilter_line(llines[0], continue_prompt)
    336 
    337         return out

/usr/local/lib/python3.5/dist-packages/IPython/core/prefilter.py in prefilter_line(self, line, continue_prompt)
    308             return normal_handler.handle(line_info)
    309 
--> 310         prefiltered = self.prefilter_line_info(line_info)
    311         # print "prefiltered line: %r" % prefiltered
    312         return prefiltered

/usr/local/lib/python3.5/dist-packages/IPython/core/prefilter.py in prefilter_line_info(self, line_info)
    250         """
    251         # print "prefilter_line_info: ", line_info
--> 252         handler = self.find_handler(line_info)
    253         return handler.handle(line_info)
    254 

/usr/local/lib/python3.5/dist-packages/IPython/core/prefilter.py in find_handler(self, line_info)
    257         for checker in self.checkers:
    258             if checker.enabled:
--> 259                 handler = checker.check(line_info)
    260                 if handler:
    261                     return handler

/usr/local/lib/python3.5/dist-packages/IPython/core/prefilter.py in check(self, line_info)
    414     def check(self, line_info):
    415         obj = self.shell.user_ns.get(line_info.ifun)
--> 416         if isinstance(obj, Macro):
    417             return self.prefilter_manager.get_handler_by_name('macro')
    418         else:

<ipython-input-1-cb6806333b6b> in __getattribute__(self, item)
      1 class A(dict):
      2     def __getattribute__(self, item):
----> 3         return self[item]
      4 

KeyError: '__class__'

如果您对此问题有任何疑问,请提供帮助。

1 个答案:

答案 0 :(得分:2)

看起来IPython正试图访问a.__class__,但失败了。它可能是作为诊断目的的某种标准物体扫描。如果您尝试print(a.__class__),则在常规Python控制台中会出现相同的错误。

如果词典中没有与该键匹配的条目,则__getattribute__应该有后备。 the documentation建议在需要访问实际属性时调用基类“__getattribute__方法”。类似的东西:

class A(dict):
    def __getattribute__(self, item):
        if item in self:
            return self[item]
        else:
            return object.__getattribute__(self, item)
            #or possibly:
            #return super().__getattribute__(item)
            #... Depending on one's interpretation of "base class"

a = A({'x' : 1})
a['x']
print(a.__class__)

覆盖__getattr__代替__getattribute__也可能有意义。这样,仍然可以访问对象的所有属性,而无需在函数中对它们进行任何显式检查。

class A(dict):
    def __getattr__(self, item):
        if item in self:
            return self[item]
        else:
            raise AttributeError

a = A({'x' : 1})
a['x']
print(a.__class__)