2016-12-29 4 views
1

Это мой первый вопрос здесь, а также мой первый проект в Python.Почему __getattribute__ fail с: TypeError: объект «NoneType» не является вызываемым

Я пытаюсь хранить экземпляры класса под названием Ip500Device:

class Ip500Device(object): 

    list = [] 
    def __init__(self, shortMac, mac, status, deviceType): 
     self.__shortMac =shortMac 
     self.__mac=mac 
     self.__status=status 
     self.__deviceType=deviceType 
     self.__nbOfObjects=0 
     Ip500Device.list.append(self)  

    def __getattribute__(self, att): 
     if att=='hello': 
      return 0 

Это первый тест просто «привет», но после того, что я хочу, чтобы получить все атрибуты.

С другой класс, я создаю объект устройства и добавить их в список:

self.__ip500DevicesLst.append(Ip500Device.Ip500Device(lst[0],lst[1],lst[2],lst[3])) 
for abcd in self.__ip500DevicesLst: 
     print abcd.__getattribute__('hello') 

Но когда я пытаюсь напечатать, программа возвращает это сообщение:

TypeError: 'NoneType' object is not callable 

I не очень хорошо понимают, как хранить экземпляры классов в Python.

+3

Нам нужно угадать, что такое '__ip500DevicesLst'. –

+1

OP довольно чистая заявляет, что '__ip500DevicesLst' - это список. Однако это не относится к вопросу, связанный с тем, почему вызов '__getattribute__' вызывает ошибку. ОП дал достаточно информации, чтобы ответить на этот вопрос, поэтому я думаю, что вопрос должен быть вновь открыт. – ekhumoro

+0

Кажется, что один из элементов в списке - «Нет». Не уверен, что это происходит из вызова метода, который вы показывали, чтобы добавить его в список или если он уже содержит «Нет». В любом случае, попробуйте проверить содержимое списка, как и ожидалось. – Basic

ответ

0

ошибка происходит потому, что __getattribute__ вызывается для всех атрибутов, и вы определили его вернуть None за все, кроме «привет». Поскольку __getattribute__ сам по себе является атрибутом, когда вы пытаетесь его вызвать, вы получите TypeError.

Эта проблема может быть исправлена ​​путем вызова метода базового класса для необработанных атрибутов:

>>> class Ip500Device(object): 
...  def __getattribute__(self, att): 
...   print('getattribute: %r' % att) 
...   if att == 'hello': 
...    return 0 
...   return super(Ip500Device, self).__getattribute__(att) 
... 
>>> abcd = Ip500Device() 
>>> abcd.__getattribute__('hello') 
getattribute: '__getattribute__' 
getattribute: 'hello' 
0 

Тем не менее, лучше определить __getattr__, так что вызываются только для атрибутов, которые не существуют:

>>> class Ip500Device(object): 
...  def __getattr__(self, att): 
...   print('getattr: %r' % att) 
...   if att == 'hello': 
...    return 0 
...   raise AttributeError(att) 
... 
>>> abcd = Ip500Device() 
>>> abcd.hello 
getattr: 'hello' 
0 
>>> abcd.foo = 10 
>>> abcd.foo 
10 

Наконец, следует отметить, что, если все, что вам нужно сделать, это атрибуты доступа по имени, вы можете использовать встроенный в getattr функции:

>>> class Ip500Device(object): pass 
... 
>>> abcd = Ip500Device() 
>>> abcd.foo = 10 
>>> getattr(abcd, 'foo') 
10 
1
print abcd.__getattribute__('hello') 

abcd.__getattribute__ не __getattribute__ метод. При попытке оценить abcd.__getattribute__, вы на самом деле вызывая

type(abcd).__getattribute__(abcd, '__getattribute__') 

который возвращает None, который затем попытаться назвать, как если бы это был метод.

Смежные вопросы