代码之家  ›  专栏  ›  技术社区  ›  matcha-tea

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

  •  2
  • matcha-tea  · 技术社区  · 8 年前

    这是我在这里的第一个问题,也是我在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 回复  |  直到 8 年前
        1
  •  1
  •   user2357112    8 年前
    print abcd.__getattribute__('hello')
    

    abcd.__getattribute__ 不是 __getattribute__ 方法当你试图评估 abcd.__getattribute__ 你实际上是在打电话

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

    返回 None ,然后尝试调用它,就好像它是一个方法一样。

        2
  •  0
  •   ekhumoro    8 年前

    发生错误的原因是: __getattribute__ 需要 全部的 属性,您已经定义了返回 None 除了“你好”以外的一切。自从 __获取属性__ 本身是一个属性,当您尝试调用它时,将得到 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