Reputation: 99
This is my first question here and also my first project in Python.
I'm trying to store instances of a class called 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
This first test is just a 'hello', but after that I want to get all the attributes.
From an other class, I'm creating devices object and adding them to a list:
self.__ip500DevicesLst.append(Ip500Device.Ip500Device(lst[0],lst[1],lst[2],lst[3]))
for abcd in self.__ip500DevicesLst:
print abcd.__getattribute__('hello')
But when I try to print, the program returns this message:
TypeError: 'NoneType' object is not callable
I don't understand really well how to store class instances in Python.
Upvotes: 2
Views: 1288
Reputation: 120568
The error happens because __getattribute__
is called for all attributes, and you have defined it to return None
for everything other than "hello". Since __getattribute__
is itself an attribute, when you try to call it you will get a TypeError
.
This problem can be fixed by calling the base-class method for unhandled attributes:
>>> 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
However, it is better to define __getattr__
, since that is only called for attributes which don't already exist:
>>> 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
Finally, note that if all you want to do is access attributes by name, you can use the built-in getattr function:
>>> class Ip500Device(object): pass
...
>>> abcd = Ip500Device()
>>> abcd.foo = 10
>>> getattr(abcd, 'foo')
10
Upvotes: 0
Reputation: 280181
print abcd.__getattribute__('hello')
abcd.__getattribute__
is not the __getattribute__
method. When you try to evaluate abcd.__getattribute__
, you're actually calling
type(abcd).__getattribute__(abcd, '__getattribute__')
which returns None
, which you then try to call as if it were a method.
Upvotes: 1