[英]Check if object attributes are non-empty python
我可以像這樣檢查 python 列表或字典是否為空
lis1, dict1 = [], {}
# similar thing can be done for dict1
if lis1:
# Do stuff
else:
print "List is empty"
如果我嘗試使用我的 class object 執行此操作,即通過鍵入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
我可以專門編寫一個 function 來檢查我的 object 屬性是否為非空,然后調用if obj1.is_attributes_empty():
,但我更感興趣的是if
評估standard data-types
(如list
和dict
)為True
或False
取決於它們包含或為空的項目。
如果我想用我的 class object 實現這個功能,我需要覆蓋或更改哪些方法?
你需要實現__nonzero__
方法(或__bool__
的__bool__)
https://docs.python.org/2/reference/datamodel.html#object。 非零
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, ...))
它在Python 2.x的Truth值測試文檔中給出 -
用戶定義的類的實例,如果類定義
__nonzero__()
或__len__()
方法,則該方法返回整數零或bool值False。
用戶定義的類的實例,如果類定義
__bool__()
或__len__()
方法,則該方法返回整數零或bool值False。
根據你的類的定義,如果定義__len__()
方法可能有意義,它返回列表長度和__len__()
的總和。然后調用此方法來確定是否將對象解釋為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
如果你的類定義(上的Py2) __nonzero__
,(上PY 3) __bool__
或(無論是) __len__
,那么這將被用來評估該類的對象的“感實性”(如果只__len__
定義,一個實例是truthy時它返回非零,並在返回零時返回虛假)。 因此,例如,要使您的類只是報告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)
的副作用獲得布爾行為。
結合使用any()
和__bool__(self)
的答案,以下代碼將允許您使用列表__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')
此代碼段將不會按預期打印任何內容。
由於許多答案和重復投票建議,您需要覆蓋__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__
。
內置vars()
function 為檢查 object 是否具有任何非空屬性提供了有用的單行代碼。 將其與__nonzero__
結合,您將得到以下結果:
def __nonzero__(self):
return any(list(vars(self).values()))
在 python 中,如果不聲明它們,您將不知道期望哪些屬性。 數據類中提供了聲明屬性的標准方法
見https://docs.python.org/3/library/dataclasses.html
from dataclasses import dataclass
@dataclass
class my_class:
lis1:list = []
dict1:dict = {}
def isEmtpy(self)->bool:
return len(self.lis1)+len(self.dict1)==0
要實施更通用的解決方案,您可能需要在https://github.com/python/cpython/blob/3.11/Lib/dataclasses.py檢查數據類源代碼,尤其是字段訪問器
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.