我可以检查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}}和list
到dict
或True
取决于它们包含的项目或为空。
如果我想用我的类对象实现此功能,我需要覆盖或更改哪些方法?
答案 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。
用户定义类的实例,如果类定义了
__bool__()
或__len__()
方法,则该方法返回整数零或bool值为False。
根据你的类的定义,如果定义__len__()
方法可能有意义,它返回列表长度和dict的总和。然后调用这个方法来确定是否解释在布尔上下文中对象为True
或False
。示例 -
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__
。