检查对象属性是否为非空python

时间:2015-09-29 05:29:23

标签: python if-statement

我可以检查python列表或字典是否为空

lis1, dict1 = [], {}
# similar thing can be done for dict1
if lis1:
    # Do stuff
else:
    print "List is empty"

如果我尝试用我的类对象执行此操作,即通过键入if my_object:来检查我的对象属性是否为空,这总是评估为True

>>> class my_class(object):
...   def __init__(self):
...     self.lis1 = []
...     self.dict1 = {}
... 
>>> obj1 = my_class()
>>> obj1
<__main__.my_class object at 0x10c793250>
>>> if obj1:
...   print "yes"
... 
yes

我可以专门编写一个函数来检查我的对象属性是否为非空,然后调用if obj1.is_attributes_empty():,但我更想知道if如何评估standard data-types之类{{} {1}}和listdictTrue取决于它们包含的项目或为空。

如果我想用我的类对象实现此功能,我需要覆盖或更改哪些方法?

5 个答案:

答案 0 :(得分:3)

您需要实现__nonzero__方法(或Python3的__bool__

https://docs.python.org/2/reference/datamodel.html#object.nonzero

class my_class(object):
    def __init__(self):
        self.lis1 = []
        self.dict1 = {}

    def __nonzero__(self):
        return bool(self.lis1 or self.dict1)

obj = my_class()
if obj:
    print "Available"
else:
    print "Not available"

Python还检查__len__方法的真实性,但这似乎对你的例子没有意义。

如果你有很多属性要检查,你可能更喜欢

return any((self.lis1, self.dict1, ...))

答案 1 :(得分:2)

Truth value testing for Python 2.x -

的文档中给出
  

用户定义类的实例,如果类定义了__nonzero__()__len__()方法,则该方法返回整数零或bool值为False。

Python 3.x -

  

用户定义类的实例,如果类定义了__bool__()__len__()方法,则该方法返回整数零或bool值为False。

根据你的类的定义,如果定义__len__()方法可能有意义,它返回列表长度和dict的总和。然后调用这个方法来确定是否解释在布尔上下文中对象为TrueFalse。示例 -

class my_class(object):
    def __init__(self):
        self.lis1 = []
        self.dict1 = {}
    def __len__(self):
        print("In len")
        return len(self.lis1) + len(self.dict1)

演示 -

>>> class my_class(object):
...     def __init__(self):
...         self.lis1 = []
...         self.dict1 = {}
...     def __len__(self):
...         print("In len")
...         return len(self.lis1) + len(self.dict1)
...
>>> obj = my_class()
>>> if obj:
...     print("yes")
...
In len
>>> obj.lis1.append(1)
>>>
>>> if obj:
...     print("yes")
...
In len
yes

答案 2 :(得分:0)

如果你的类定义(在Py2上)__nonzero__,(在Py3上)__bool__或(在任何一个上)__len__,那么这将用于评估&#34;真实性& #34;该类的对象(如果仅定义__len__),当它返回非零时,实例是真实的,当它返回零时,实例是虚假的)。因此,举例来说,为了让你的课只报告Py2或Py3中的属性是非空的,你要添加:

 def __bool__(self):
     return bool(self.lis1 or self.dict1)
 __nonzero__ = __bool__ # To make it work on Py2 too

或者,如果您的类实例具有有意义的长度,则定义:

 def __len__(self):
     return len(self.lis1) + len(self.dict1)  # For example; I doubt the length is meaningful in terms of both

并通过支持len(myobject)的副作用获得布尔行为。

答案 3 :(得分:0)

结合使用any()__bool__(self)的答案,以下代码将允许您使用列表解析检查所有属性。

class my_class(object):
    def __init__(self):
        self.list1 = []
        self.dict1 = {}

    def __bool__(self):
        check = any([self.__dict__[attr] for attr in self.__dict__.keys()])

        return check

obj1 = my_class()

if obj1:
    print('yes')

此代码段不会按预期打印任何内容。

答案 4 :(得分:0)

由于许多答案和重复投票建议,您需要覆盖__nonzero__方法。但是,从您的评论中,您还希望避免显式枚举属性。这可以通过这样的技巧来完成:

class Example(object):
    def __init__(self):
        self._values = {}
        self.attr1 = []
        self.attr2 = {}

    def __setattr__(self, name, value):
        self.__dict__[name] = value
        if not name.startswith('_'):
            self._values[name] = value  # keep track of the assigned attributes

    def __nonzero__(self):
        return any(self._values.itervalues())

它处理稍后分配或修改的所有公共属性:

>>> ex = Example()
>>> bool(ex)
False
>>> ex.attr1.append('data')
>>> bool(ex)
True
>>> ex.attr1.pop()
>>> ex.attr3 = 42
bool(ex)
>>> False

未正确处理属性删除,因为您需要覆盖__delattr__