为什么__getattribute__失败:TypeError:'NoneType'对象不可调用

时间:2016-12-29 19:58:37

标签: python typeerror getattribute

这是我在这里的第一个问题,也是我在Python中的第一个项目。

我正在尝试存储名为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

我不太清楚如何在Python中存储类实例。

2 个答案:

答案 0 :(得分:1)

print abcd.__getattribute__('hello')

abcd.__getattribute__不是__getattribute__方法。当您尝试评估abcd.__getattribute__时,您实际上正在调用

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

返回None,然后您尝试将其称为方法。

答案 1 :(得分:0)

发生错误是因为为{em>所有属性调用了__getattribute__,并且您已将其定义为除“hello”以外的所有内容返回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