Ошибка при работе с пользовательскими классами в консоли ipython - PullRequest
0 голосов
/ 25 мая 2018

Сначала я должен сказать, что я использую 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 голосов
/ 25 мая 2018

Похоже, IPython пытается получить доступ к a.__class__ и не работает.Вероятно, это делается как некий стандартный набор объектов для диагностических целей.В обычной консоли Python вы получите ту же ошибку, если попытаетесь print(a.__class__).

. У вашего __getattribute__ должен быть запасной вариант, если в словаре нет записи, соответствующей ключу. документация рекомендует вызывать метод базового класса '__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__)
...